#!/usr/bin/perl

use strict;

use Getopt::Long;

use lib '/app/tools/data_classes/lib';

use lib '/app/tools/common/lib';

#use Common::Consts;

#/////////////////////////////////////////////////
my $DATA_DIR        = '/app/data';
my $DB_INIT_FILE    = '/app/tools/dbadmin/sql/create/C_CLIENT_DATABASE.sql';
my $COMMON_DB       = 'RSCOMMON';
my $IMPORT_SCRIPT   = '/app/tools/data_classes/bin/product/import_product_catalog.pl';
my $EXTRACT_SCRIPT  = '/app/tools/data_classes/bin/product/update_product_catalog_extract.pl';
my $PATTERN_SCRIPT  = '/app/tools/data_classes/bin/product/update_product_pattern_match.pl';
my $OPTIMIZE_SCRIPT = '/app/tools/dbadmin/sql/optimize.sql';

#/////////////////////////////////////////////////

my ( $dbName, $clientName, $clientDir, $cid );
GetOptions(
    'db=s'   => \$dbName,
    'name=s' => \$clientName,
    'dir=s'  => \$clientDir,
    'cid=i'  => \$cid,
);

if ($cid) {
    require Common::Consts;
    require Client::Client;
    $dbName = $Common::Consts::CLIENT_DB{$cid}{db_name} || die "invalid cid\n";
    $clientName = Client::Client->new( client_id => $cid )->ClientName;
} else {
    $dbName = uc($dbName);
}
$clientDir =~ s#^$DATA_DIR/##;
$clientDir =~ s#/$##;

unless ( ( $dbName && $clientName && $clientDir ) or ( $clientDir && $cid ) ) {
    die <<EofDIE;
$0 -db <client_db_name> -name <client_name> -dir <client_dir_name>
or
$0 -cid <client_id> -dir <data_dir>
EofDIE
}
substr( $dbName, 0, 0 ) = 'C_' unless ( $dbName =~ /^C_/ );

# get the next id
my $clientID = $cid || `mysql -uroot -e "select max(client_id) from client where client_id < 999" $COMMON_DB`;
$clientID =~ s/.*\s(\d+)\s.*$/$1+1/e;
my $dirExists = -d "$DATA_DIR/$clientDir" ? 'already created' : 'not created yet';

print qq|
Please review the following and confirm:

client ID will be       '$clientID'
db name will be         '$dbName'
client name will be     '$clientName'
client dir name will be '$clientDir' ($dirExists)

Is this correct (y/n)?|;

my $confirm = <STDIN>;
exit unless ( $confirm =~ /^y/i );

_init_db() unless ($cid);

_confirm_module_updates( $clientID, $dbName );

my $catalogFile = _getCatalogFileName() || '?';
print "\ncatalog data file name ($DATA_DIR/$clientDir/$catalogFile):";
my $entry = <STDIN>;
chomp $entry;
$catalogFile = $entry if $entry;

while ( !-r "$DATA_DIR/$clientDir/$catalogFile" ) {
    print "can't read $DATA_DIR/$clientDir/$catalogFile\nplease re-enter:";
    $catalogFile = <STDIN>;
    chomp $catalogFile;
}

print "\nimporting catalog data...\n";
die "\nstopping - import aborted\n" if system("$IMPORT_SCRIPT -c $clientID -f $DATA_DIR/$clientDir/$catalogFile");

my $count = `mysql -uroot -e "select count(*) from product_catalog_extract" $dbName`;
$count =~ s/.*\s(\d+)\s.*$/$1/;
if ( $count > 0 ) {
    print 'product_catalog_extract has content.  truncate it and press enter to continue:';
    <STDIN>;
}
$count = `mysql -uroot -e "select count(*) from product_pattern_match" $dbName`;
$count =~ s/.*\s(\d+)\s.*$/$1/;
if ( $count > 0 ) {
    print 'product_pattern_match has content.  truncate it and press enter to continue:';
    <STDIN>;
}

print "\nbuilding catalog extract table...\n";
die "\nstopping - catalog extract failed\n" if system("$EXTRACT_SCRIPT -c $clientID");

my $patternInputFile = sprintf( "%s/%s/product_pattern_match.txt", $DATA_DIR, $clientDir );

print "\nbuilding pattern match table input file in $patternInputFile...\n";
die "pattern script failed\n" if system("$PATTERN_SCRIPT -c $clientID > $patternInputFile");

# mysql doesn't like the 'app' link so change to true path
$patternInputFile =~ s#^/app#/usr/app#;
print "\nloading inputfile...\n";
die "pattern file load failed\n"
  if system(
qq|mysql -uroot -e "load data infile '$patternInputFile' into table product_pattern_match (product_id, product_type, match_md5, pattern, level, date_created)" $dbName|
  );

print "\noptimizing db...\n";

#system("mysql -uroot -e \"source $OPTIMIZE_SCRIPT\" $dbName");
die "optimizaion failed\n" if system("mysql -uroot $dbName < $OPTIMIZE_SCRIPT");

print "\ndone!\n";

sub _init_db {
    print "\ncreating and initializing db...\n";

    # create the DB
    die "db create error\n" if system("mysqladmin -uroot create $dbName");

    # init the db
    die "db init error\n" if system("mysql -uroot $dbName < $DB_INIT_FILE");

    # populate pattern_level table
    die "pattern level copy error\n" if system("mysqldump -t -uroot C_SONY pattern_level | mysql -uroot $dbName");

    # populate format table
    die "format copy error\n" if system("mysqldump -t -uroot C_SONY format | mysql -uroot $dbName");

    # add "unknown" service
    die "insert unknown service error\n"
      if system(
qq|mysql -uroot -e "insert into service (service_id, service_name, service_name_clean, date_created) values (0, 'Unknown', 'unknown', now())" $dbName|
      );

    # insert into RSCOMMON client table
    die "insert new client error\n"
      if system(
        qq|mysql -uroot -e "insert into client (client_id, client_name, date_created) values ($clientID, '$clientName', now())" $COMMON_DB|
      );

}

sub _confirm_module_updates {
    my ( $cid, $dbid ) = @_;
    print <<EofCONFIRM;

are the following packages updated?:

/app/tools/common/lib/Common/Consts.pm
* CLIENT_NAME_CLEAN
* CLIENT_DB
* CLIENT_SALE_AGG

/app/tools/data_classes/lib/Client/Client.pm
* declare constant k<ClientName>
* add to \%gPreferences

EofCONFIRM

    $confirm = '';
    while ( $confirm ne 'y' ) {
        print 'enter y to continue:';
        $confirm = <STDIN>;
        chomp $confirm;
    }

    require Common::Consts;

    die "\%CLIENT_NAME_CLEAN{$cid} is not defined properly\n"
      unless ( defined $Common::Consts::CLIENT_NAME_CLEAN{$cid} );
    die "\%CLIENT_DB{$cid} is not defined properly\n"
      unless ( defined $Common::Consts::CLIENT_DB{$cid} && $Common::Consts::CLIENT_DB{$cid}{db_name} eq $dbid );
    die "\%CLIENT_SALE_AGG{$cid} is not defined properly\n"
      unless ( defined $Common::Consts::CLIENT_SALE_AGG{$cid} && scalar keys( %{ $Common::Consts::CLIENT_SALE_AGG{$cid} } ) == 4 );

}

sub _getCatalogFileName {
    return unless opendir( DATADIR, "$DATA_DIR/$clientDir" );

    my $maxModTime = 0;
    my $newestFile = '';
    foreach my $file ( grep /\.(txt|tsv|tab)$/, readdir(DATADIR) ) {
        my $modTime = ( stat("$DATA_DIR/$clientDir/$file") )[9];
        if ( $modTime > $maxModTime ) {
            $maxModTime = $modTime;
            $newestFile = $file;
        }
    }
    closedir(DATADIR);

    return $newestFile;
}

