#!/usr/bin/perl 
use lib("/www/opals/module");
use strict;
use Getopt::Std;
use Date::Calc::Object qw(
    :all
);
use Digest::SHA qw(
    sha1_hex
    sha512_hex
);

use POSIX qw(
    ceil
    floor
);

use Time::localtime;


use Business::ISBN;
use Opals::Marc::Record;
use MARC::Record;
use MARC::Field;
use MARC::File::XML;


my %options = ();
getopts("c:f:",\%options);
my $configFile = $options{c};
my $lexileFile = $options{f};
if(!$lexileFile || ! -f $lexileFile){
    $lexileFile="/data/opals/lexile/lexile.sql";
};
if (!$configFile || ! -f $configFile || !$lexileFile || ! -f $lexileFile) {
    print "Usage: $0 -c CONFIG_FILE -f LEXILE_FILE \n";
    exit 1;
}

use DBI;
my $config = loadConfig($configFile);
my $adminConfig = loadConfig('/etc/opals/opalsrc');
my $dbh = makeConnection($config);

my $zRoot   =   $config->{'zRoot'};
my $zPort   =   $config->{'zPort'};
my $zDatabase = $config->{'zDatabase'};

my $db_host     = $config->{'db_host'};
my $db_user     = $config->{'db_user'};
my $db_name     = $config->{'db_name'};
my $db_password = $config->{'db_password'};

my $db_name_admin     = $adminConfig->{'sql_addsite_user'};
my $db_password_admin = $adminConfig->{'sql_addsite_pass'};


system("mysql -u$db_name_admin -p$db_password_admin -h$db_host $db_name <$lexileFile");


my $sth_lexile=$dbh->prepare("select lexile,code from lexile where isbn13=?");
my $sth=$dbh->prepare("select distinct rid from opl_item where barcode not regexp '^___' ");
$sth->execute();
my $marc;

while(my ($rid)=$sth->fetchrow_array){
    $marc = _getRecordByRid($rid);
    if (!$marc) {
        next;
    }
    my $isbn13=getISBN13($marc);
    if($isbn13 ){
        my $lx= getLexile($isbn13);
        if($lx){
            printf "rid:%s\tisbn:%s\tlexile:%s %s\n",$rid,$isbn13,$lx->{'code'},$lx->{'lexile'};
            updateMarcLexile($rid,$marc,$lx->{'code'},$lx->{'lexile'}) 
        }
    }
}
############################################################
sub getLexile{
    my($isbn13)=@_;
    my $ret=undef;
    $sth_lexile->execute($isbn13);
    if(my ($lexile,$code)=$sth_lexile->fetchrow_array){
        $ret={code=>$code,lexile=>$lexile};
    }
    return $ret;
}
############################################################
sub _getRecordByRid {
    my ($rid) = @_;
    my $xml = '';
    my $dir     = "$zRoot/$zPort/record/$zDatabase/" . ceil($rid/1000);
    if (! -f "$dir/$rid.xml") {
        print "ERROR: $dir/$rid.xml: not found.\n";
        return;
    }
    open RECORD, "<$dir/$rid.xml";
    while (<RECORD>) {
        $xml .= $_; 
    }
    close RECORD;
    my $marc = Opals::Marc::Record::newFromXml($xml);
    return $marc;
}
############################################################


sub getRidFromMarc {
    my ($marc) = @_;

    if (!$marc) {
        return;
    }

    my $f001 = $marc->field('001');
    if (!$f001) {
        return;
    }

    return $f001->data();
}
############################################################

sub getISBN13{
    my ($marc) = @_;
    my $isbn13=undef;
    my @fields=$marc->field('020');

    foreach my $f (@fields) {
            my $data = $f->subfield('a');
            if (!$data || $data eq '') {
                $data= $f->subfield('z');
            }

            if (!$data) {
                next;
            }
            eval{
            $data=~ s/^([\D]*)([0-9]+)(.*)/$2/g;
            my $isbn_obj = Business::ISBN->new($data) || next;
            $isbn13 = $isbn_obj->as_isbn13;
            $isbn13 = $isbn13->as_string([]);
            } or next;

    }
    return $isbn13;

}
#==================================================================================================
sub updateMarcLexile{
    my($rid,$marc,$code,$lexile)=@_;
    my $dir     = "$zRoot/$zPort/record/$zDatabase/" . ceil($rid/1000);
    my $lVal="$code $lexile";
    $lVal=~ s/^ +| +$//g;
    my $lexileField = MARC::Field->new( 521, '8', '0', 'a' => $lVal,'b' => 'Lexile');
 
    my @fields=$marc->field('521');
    my $updateed=0;
    foreach my $f(@fields){
        if($f->indicator(1) ==8){
            if($f->subfield('b') =~/lexile/i){
                $f->update('a'=>$lVal);
                $updateed=1;
            }
        }
    }
    if(!$updateed){
        $marc->insert_fields_ordered($lexileField);
    }
    my $xml = MARC::File::XML::record($marc);
    open RECORD, ">$dir/$rid.xml";
    print RECORD $xml;
    close RECORD
}
############################################################
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;
} 

$| = 1;

