#!/usr/bin/perl

use strict;
use DBI;
use Fcntl;

my $check_prg = 'zebraidx';
if (`ps -ef | grep -e zebra-index.tbz -e $check_prg | grep -v grep`) {
    print "[WARN] $check_prg is running.\n";
    exit 1;
}

my $scriptname = `basename $0`;
chomp $scriptname;
my $isRunning = `ps -ef | grep $scriptname | grep perl | grep -v grep | /usr/bin/wc | /bin/gawk '{print \$1}'`;
chomp($isRunning);
if ($isRunning > 1) {
    print "is running...\n";
    exit 1;
}
#sleep 5;

# Fix z-index if it is bad
system "/root/bin/zindex_fix";

# Check user
if ($ENV{'LOGNAME'} ne 'root') {
    print STDERR "$scriptname: run by $ENV{'LOGNAME'}\n";
    exit 2;
}
#/Check user

## Check if script is running
#my $lockDir = '/var/lock/subsys/opals';
#if (!-d $lockDir) {
#    `mkdir -p $lockDir`;
#}
#
#my $lockFile = "$lockDir/$scriptname";
#sysopen(LOCK, $lockFile, O_WRONLY|O_CREAT|O_EXCL, 0600) || die $!;
##/Check if script is running

my $OPALS_CONF_DIR  = `dirname $0`;
chomp($OPALS_CONF_DIR);
$OPALS_CONF_DIR .= '/../conf';

my ($code, $config, $zDir, $dir, $path, $max_rid, 
    $dbh, $sth_dir, $sth_update, $sth_max_rid);

END {
    if ($dbh) {
        $dbh->disconnect();
    }
}

my @values;
open SITECODE, "ls $OPALS_CONF_DIR | ";
while (<SITECODE>) {
    $code = $_;
    chomp $code;
    $config = loadConfig("$OPALS_CONF_DIR/$code");
    $dbh = makeConnection($config);

    $zDir = "$config->{'zRoot'}/$config->{'zPort'}/record/".
            $config->{'zDatabase'};

    if (!$config->{'zindex'} || $config->{'zindex'} !~ m/^on$/i ||
        ! -d $zDir || !$dbh) {
        next;
    }

    # Z-indexing records
    print "Z-indexing database $config->{'zDatabase'}:\n";

    ($sth_dir, $sth_update, $sth_max_rid) = prepare_sth($dbh);
    $sth_dir->execute();
    while (($dir) = $sth_dir->fetchrow_array) {
        $sth_max_rid->execute($dir);
        ($max_rid) = $sth_max_rid->fetchrow_array();

        zindex($config, $dir);
        $sth_update->execute($dir, $max_rid);
    }
    $sth_dir->finish;
    $sth_update->finish;
    print "Done.\n";

    # Update import status
    updateImportStatus($dbh);

    $dbh->disconnect();
    $dbh = undef;
}
close SITECODE;

## Remove lock file
#close LOCK;
##unlink $lockFile;
#system("/bin/rm -f $lockFile");
##/Remove lock file

exit 0;
################################################################################


sub makeConnection {
    my ($config) = @_;
    if (!$config) {
        return;
    }
    my ($db_driver, $db_name, $db_host, $db_port, $db_user, $db_password);

    $db_driver   = $config->{'db_driver'} || 'mysql';
    $db_name     = $config->{'db_name'};
    $db_host     = $config->{'db_host'};
    $db_port     = $config->{'db_port'}   || '3306';
    $db_user     = $config->{'db_user'};
    $db_password = $config->{'db_password'};

    my $dsn = "dbi:$db_driver:$db_name:$db_host:$db_port";

    return DBI->connect($dsn, $db_user, $db_password);
}
############################################################


sub loadConfig {
    my ($configFile) = @_;
#    print "Enter the config filename of Opals: ";
#    $configFile = <STDIN>;
    my $config = {};

    open CONF, $configFile || die "Cannot open file $configFile";
    while (<CONF>) {
        chomp;
        s/#.*//;                # remove comments
        next if /^\s*$/;        # ignore blank lines

        if (/^\s*(\w+)\s*=\s*(.*?)\s*$/) {
            $config->{$1} = $2;
        }
    }
    close CONF;
    
    return $config;
}
############################################################


sub prepare_sth {
    my ($dbh) = @_;
    my $sth_dir = $dbh->prepare(<<_SQL_);
select  ceil(rid/1000) as dir
from    opl_marcRecord
where   zIndexed = 0
group by dir
_SQL_
    my $sth_update = $dbh->prepare(<<_SQL_);
update  opl_marcRecord
set     zIndexed = 1
where   ceil(rid/1000) = ?
     && rid <= ?
_SQL_
    my $sth_max_rid = $dbh->prepare(<<_SQL_);
select  max(rid) as max_rid
from    opl_marcRecord
where   zIndexed = 0
     && ceil(rid/1000) = ?
_SQL_

    return ($sth_dir, $sth_update, $sth_max_rid);
}
############################################################


sub zindex {
    my ($config, $dir) = @_;
    my ($zebraidx, $zRoot, $zPort, $zDatabase, $path);
    $zebraidx  = $config->{'zebraidx'};
    $zRoot     = $config->{'zRoot'};
    $zPort     = $config->{'zPort'};
    $zDatabase = $config->{'zDatabase'};

    $zebraidx = "LANG=en_US.UTF-8 $zebraidx -c $zRoot/$zPort/zebra.cfg";
    my $zLog = "$zRoot/$zPort/log/zebraidx.log";

    $path = "$zRoot/$zPort/record/$zDatabase/$dir";
    print "\t$path\n";

    system("chown -R apache.apache $path");
    system("$zebraidx -d $zDatabase update $path >> $zLog 2>&1");
    system("$zebraidx commit >> $zLog 2>&1");
}
############################################################


sub updateImportStatus {
    my ($dbh) = @_;

    my $sth_indexing = $dbh->prepare(<<_SQL_);
select  iid
from    opl_marcImport
where   status = 'indexing'
order by iid
_SQL_
    my $sth_checkIndex = $dbh->prepare(<<_SQL_);
select  count(*) as isIndexing
from    opl_item as i, opl_marcRecord as r
where   i.importId = ?
     && i.rid      = r.rid
     && r.zIndexed = 0
_SQL_
    my $sth_updateStatus = $dbh->prepare(<<_SQL_);
update  opl_marcImport
set     status = 'done'
where   iid = ?
_SQL_

    $sth_indexing->execute();
    my ($iid, $isIndexing);
    while (($iid) = $sth_indexing->fetchrow_array) {
        $sth_checkIndex->execute($iid);
        ($isIndexing) = $sth_checkIndex->fetchrow_array;
        if (!$isIndexing) {
            $sth_updateStatus->execute($iid);
        }
    }
    $sth_updateStatus->finish;
    $sth_checkIndex->finish;
    $sth_indexing->finish;
}
############################################################
