#!/usr/bin/perl -w

use strict;
use DBI;
use Getopt::Std;
use POSIX qw(
    ceil
);

my %options = ();
getopts("c:",\%options);
my $configFile = $options{c};
if (!$configFile || ! -f $configFile) {
    print "Usage: $0 -c CONFIG_FILE\n";
    exit 1;
}

my $config = loadConfig($configFile);
my $dbh = mankConnection($config);
END {
    if ($dbh) {
        $dbh->disconnect();
    }
}

$| = 1;
# Codes start...

my $zdbDir = $config->{'zRoot'} .'/'
           . $config->{'zPort'} .'/'
           . 'record' .'/'
           . $config->{'zDatabase'};

my $indexDir;

my $sth = $dbh->prepare(<<_SQL_);
select  distinct rid
from    opl_item
order by rid asc
_SQL_
$sth->execute;
my $dir;
while (my ($rid) = $sth->fetchrow_array) {
    $dir = fixRecord($dbh, $zdbDir, $rid);
    if ($dir) {
        $indexDir->{$dir} = 1;
    }
}
$sth->finish;

update_zIndex($config, $zdbDir, $indexDir);

# Codes end.

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


sub mankConnection {
    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 fixRecord {
    my ($dbh, $zdbDir, $rid) = @_;

    my $record = '';
    my $dir = ceil($rid/1000);
    if (! -f "$zdbDir/$dir/$rid.xml") {
        return;
    }

    open MARCXML, "<$zdbDir/$dir/$rid.xml";
    while (<MARCXML>) {
        $record .= $_;
    }
    close MARCXML;

    #print "************** Before:\n$record\n";
    $record = fixChar($record);
    #print "************** After:\n$record\n";
    update_record($record, $zdbDir, $rid);
    update_sql($dbh, $record, $rid);

    return $dir;
}
############################################################


sub fixChar {
    my ($string) = @_;

    $string =~ s/ï¿½e/é/g;
    $string =~ s/ï¿½E/É/g;
    $string =~ s/ï¿½i/î/g;
    $string =~ s/ï¿½I/Î/g;
    $string =~ s/ï¿½c/ç/g;
    $string =~ s/ï¿½C/Ç/g;
    $string =~ s/ï¿½a/à/g;
    $string =~ s/ï¿½A/À/g;

    return $string;
}
############################################################


sub update_record{
    my ($record, $zdbDir, $rid) = @_;

    my $dir = ceil($rid/1000);
    open MARCXML, ">$zdbDir/$dir/$rid.xml";
    print MARCXML $record;
    close MARCXML;
}
############################################################


sub update_sql{
    my ($dbh, $record, $rid) = @_;

    my $str;
    # title:    "$sf245a: ($sf245b || $sf245p)"
    my $title = getSubField($record, '245', 'a');
    $str = getSubField($record, '245', 'b');
    if (!$str) {
        $str = getSubField($record, '245', 'p');
    }
    if ($str) {
        $title .= ": $str";
    }

    # author:   "$sf100a"
    my $author = getSubField($record, '100', 'a');

    # pubPlace: "$sf260a"
    my $pubPlace = getSubField($record, '260', 'a');

    # pubName:  "$sf260b"
    my $pubName = getSubField($record, '260', 'b');

    # pubDate:  "$sf260c"
    my $pubDate = getSubField($record, '260', 'c');

    my $sql = <<_SQL_;
update  opl_marcRecord
set     title    = ?,
        author   = ?,
        pubPlace = ?,
        pubName  = ?,
        pubDate  = ?
where   rid = ?
_SQL_
    my @values = ($title, $author, $pubPlace, $pubName, $pubDate, $rid);
    my $rv = $dbh->do($sql, undef, @values);

    return $rv;
}
############################################################


sub update_zIndex{
    my ($config, $zdbDir, $indexDir) = @_;
    my $zebraidx  = $config->{'zebraidx'};
    my $zDir      = "$config->{'zRoot'}/$config->{'zPort'}";
    my $zConfig   = "$zDir/zebra.cfg";
    my $zDatabase = $config->{'zDatabase'};
    my $zLog      = "$zDir/log/zebraidx.log";

    my $dir;
    foreach my $d (sort keys %{$indexDir}) {
        $dir = "$zdbDir/$d";
        print "Updating $dir\n";
        system "$zebraidx -c $zConfig -d $zDatabase update $dir >> $zLog 2>&1";
        system "$zebraidx -c $zConfig commit                    >> $zLog 2>&1";
    }
}
############################################################


sub getSubField {
    my ($xml, $tag, $sfcode) = @_;

    my $data;
    if ($xml =~ m/([\s]*<datafield tag="$tag" ind1="[\d ]" ind2="[\d ]">([\s]*<subfield code="[\w\-]">.*<\/subfield>)+[\s]*<\/datafield>)/) {
        if ($1 =~ m/<subfield code="$sfcode">(.*)<\/subfield>/) {
            $data = $1;
        }
    }

    return $data;
}
