#!/usr/bin/perl 

use lib "/www/odev/module";;
use Opals::Context('/etc/opals/conf/opl_ha');
use strict;
use Opals::UrlRegistry qw(
    ureg_getUrlRegistry
    ureg_getMenu
);
use Time::HiRes qw( time );
use CGI;
use DBI;
use Text::CSV_XS;
use Opals::Date qw(
    date_parse
);
use MARC::Record;
use MARC::Field;
use MARC::File::XML;
use MARC::File::USMARC;
use Opals::Marc::Record;
use MARC::Record;
use MARC::Field;
use MARC::File::XML;

use Class::CSV;
use JSON;

use Opals::BackgroundJobs qw(
    bgjob_create
    bgjob_execute
    bgjob_getStatus
    bgjob_getOutput
);
use Opals::MarcXml qw(
    mxml_update
    mxml_del_rec_holding
    mxml_cpDatafield
    mxml_mvDatafield
    mxml_addDatafield
    mxml_delDatafield
    mxml_delSubfield
    mxml_cpSubfield
    mxml_mvSubfield
    mxml_addSubfield
    mxml_datafieldReplace
    mxml_updateFieldInd
    mxml_updateItemType
    mxml_updateRecType
    mxml_mergeHolding
);
use  Opals::Utility qw(
    util_getXmlRecord
);
use Opals::Session qw(
    SessionHdl_viewMovingHolding
    SessionHdl_mhPrevNextRecord
    SessionHdl_moveHolding
    SessionHdl_setTarget
    SessionHdl_add
    SessionHdl_del
    SessionHdl_get
    SessionHdl_clearVar
    SessionHdl_exist_rid
    SessionHdl_exist_bc
    SessionHdl_count
    SessionHdl_getBriefRecList
    SessionHdl_getBrRecListByHolding
    SessionHdl_getSSID
);
my $cgi = CGI->new;
my $input = $cgi->Vars();
my $rid =101;




my $dbh = Opals::Context->dbh();
END { $dbh->disconnect(); }

bgjob_execute($dbh,34);
exit 0; 
#SessionHdl_add($dbh,"93e5732ceed03ae498b1e98f46cf9d679a5f8531","ge_rid",2257);





my $marcJson1="";
my $marcJson2="";
my($xml1,$xml2)=('','');

my $test= getGERecFromSession($dbh,1);
my $ridBcList=[$test];
$xml1 =util_getXmlRecord($test->{'rid'});
my $marcJson1 =getMarcJsonOBj($xml1);

my $job={"action"=>"addDatafield", "param"=>{"sfList"=>[{"data"=>"test","code"=>"8"}],"ind1"=>"1","ind2"=>"","tag"=>"110"}};
#my $ridBcList=[{"rid"=>32,bcList=>[]}];

$xml2 =_marcGlobalEdit($dbh,$job,$ridBcList);

$xml1 =util_getXmlRecord(32);
my $marc = Opals::Marc::Record::newFromXml($xml1);

my $file = MARC::File::XML->out( "/tmp/32_o.xml");
$file->write($marc);

$file->close();

my $newMarcJson =getMarcJsonOBj($xml2);
getDiffField($marcJson1,$newMarcJson);

print to_json($newMarcJson,{pretty=>1});
############################################################
#
sub _marcGlobalEdit{
    my($dbh,$job,$ridBcList)=@_;
    # $job    {"action":"addDatafield",
    #          "type":"marcGlobalEdit",
    #          "param":{"sfList":[{"data":"test","code":"8"}],"ind1":"1","ind2":"","tag":"110"}} 
    # 
    # $ridBcList {"rid":    , 
    #            "bcList": [bc1,bc2,...]}
    my $xml=undef;
    my $GE_FN_MAP={
       
       addDatafield     =>\&mxml_addDatafield,
       addSubfield      =>\&mxml_addSubfield,
       cpDatafield      =>\&mxml_cpDatafield,
       cpSubfield       =>\&mxml_cpSubfield,
       delDatafield     =>\&mxml_delDatafield,
       mvDatafield      =>\&mxml_mvDatafield,
       delSubfield      =>\&mxml_delSubfield,
       mvSubfield       =>\&mxml_mvSubfield,
       datafieldReplace =>\&mxml_datafieldReplace,
       updateFieldInd   =>\&mxml_updateFieldInd,
       updateItemType   =>\&mxml_updateItemType,
       updateRecType    =>\&mxml_updateRecType

    };

    if(defined $GE_FN_MAP->{$job->{'action'}}){
        my $fn= $GE_FN_MAP->{$job->{'action'}};
        foreach my $item (@$ridBcList){
            my $rid=$item->{'rid'};
            my $bcList=$item->{'bcList'};
            $xml = util_getXmlRecord($rid) || next;
            $job->{'param'}->{'rid'}=$rid;
            $job->{'param'}->{'bcList'}=$bcList;
            $xml = &$fn($xml,$job->{'param'});
        }
    }
    return $xml;
}
############################################################
sub getGERecFromSession{
    my ($dbh,$recPos)=@_;
    my $ridBcList={};
    my $bcList=[];
    my ($rid) =$dbh->selectrow_array("select distinct rid from opl_sessionVar where var='ge_rid' limit $recPos,1");
    if($rid){
        $ridBcList={rid=>$rid,bcList=>[]};
        my $sth=$dbh->prepare("select barcode from opl_sessionVar where rid=? && var='ge_rid'");
        $sth->execute($rid);
        while(my ($bc)=$sth->fetchrow_array){
            push @{$ridBcList->{'bcList'}},$bc;
        }
    }
    return $ridBcList;

}

#////////////////////////////////////////////////////////////////////////////
#
sub getMarcJsonOBj{
    my ($xml) = @_;
    my $marc={};
    my @fields=();

    if($xml =~ s/<leader>(.*?)<\/leader>//){
        $marc->{'leader'}=$1;
    }
    while($xml =~ s/<controlfield tag="(\d{3})">(.*?)<\/controlfield>//){
        push @fields,[$1,$2];
    }
    while($xml =~ s/<datafield tag="(\d{3})" ind1="(\s|\d)" ind2="(\s|\d)">(.*?)<\/datafield>//s){
        my($tag,$ind1,$ind2,$sf)=($1,$2,$3,$4);
        my @f=($tag,$ind1,$ind2);
        my @sfList=();
        while($sf =~s/<subfield code="(.?)">(.*?)<\/subfield>//){
            push @sfList,[$1,$2] if($1 ne '-');
        }
        push @f,\@sfList;
        push @fields,\@f;
    }
    $marc->{'fields'}=\@fields;
    return $marc;



}

############################################################
sub json2Xml{
    my($marcJson)=@_;
    my $cfFmt="  <controlfield tag=\"%s\">%s</controlfield>\n";
    my $dfFmt="  <datafield tag=\"%s\" ind1=\"%s\" ind2=\"%s\">\n%s  </datafield>\n";
    my $sfFmt="    <subfield code=\"%s\">%s</subfield>\n";
    my $xml="<record>\n";
    $xml .="  <leader>". $marcJson->{'leader'} ."</leader>\n";
    foreach my $f(@{$marcJson->{'fields'}}){
        my $tag=@$f[0];
        if(@$f[0] lt "010"){
            $xml .=sprintf $cfFmt,$tag,@$f[1];
        }
        else{
            my $ind1=(@$f[1]=~ m/^\d$/)?@$f[1]:' ';
            my $ind2=(@$f[2]=~ m/^\d$/)?@$f[2]:' ';
            my $sfList=@$f[3];
            my $sfListXml="";
            foreach my $sf(@$sfList){
                $sfListXml .= sprintf $sfFmt,@$sf[0],@$sf[1];
            }
            $xml .=sprintf $dfFmt,$tag,$ind1,$ind2,$sfListXml;
        }
    }
    $xml .="</record>";
    return $xml;
}


#
############################################################
sub getDiffField{
    my ($marcJson1,$marcJson2)=@_;
    my $fields_1=$marcJson1->{'fields'};
    my $fields_2=$marcJson2->{'fields'};
    my $match=0;
    if($marcJson1->{'leader'} ne $marcJson2->{'leader'}){
        $marcJson1->{'leaderChanged'}=1;
        $marcJson2->{'leaderChanged'}=1;
    }
    foreach my $f1(@$fields_1){
        foreach my $f2(@$fields_2){
            next if((@$f2[0] lt "010" && scalar(@$f2)>2) ||(@$f2[0] ge "010" && scalar(@$f2)>4));
            if(@$f1[0] eq @$f2[0]){
                if(to_json($f1) eq to_json($f2)){
                    push @$f1,"";
                    push @$f2,"";
                    last;
                }
            }
        }
    }
    foreach my $f1(@$fields_1){
         next if((@$f1[0] lt "010" && scalar(@$f1)>2) ||(@$f1[0] ge "010" && scalar(@$f1)>4) );
         $match=0;
         foreach my $f2(@$fields_2){
            next if((@$f2[0] lt "010" && scalar(@$f2)>2) ||(@$f2[0] ge "010" && scalar(@$f2)>4) );
            if(@$f1[0] eq @$f2[0] && to_json($f1) ne to_json($f2)){
                    push @$f1,"!";
                    push @$f2,"!";
                    getDiffSubfield(@$f1[3],@$f2[3]) if(@$f1[0] ge "010");
                    $match=1;
                    last;
            }
         }
         if(!$match){
              push @$f1,"-";
         }
    }
    foreach my $f2(@$fields_2){
        next if((@$f2[0] lt "010" && scalar(@$f2)>2) ||(@$f2[0] ge "010" && scalar(@$f2)>4) );
        push @$f2,"+";
    }
}
############################################################

sub getDiffSubfield{
    my($sfList1,$sfList2)=@_;
    my @tmp=();
    my $match=0;
    foreach my $sf1(@$sfList1){
        $match=0;
        for(my $j=0;$j<scalar(@$sfList2);$j++){
            my $sf2=@{$sfList2}[$j];
            if(@$sf1[0] eq @$sf2[0] && @$sf1[1] eq @$sf2[1]){
                #splice @{$sfList2},$j,1;
                push @$sf1,"";
                push @$sf2,"";
                $match=1;
                last;
            }
        }
        if(!$match){
            push @tmp,$sf1;
        }
    }
    foreach my $sf1(@tmp){
        $match=0;
        for(my $j=0;$j<scalar(@$sfList2);$j++){
            my $sf2=@{$sfList2}[$j];
            next if(scalar(@$sf2)>2);
            if(@$sf1[0] eq @$sf2[0] && @$sf1[1] ne @$sf2[1]){
                push @$sf1,"!";
                push @$sf2,"!";
                $match=1;
                last;
            }
        }
        if(!$match){
            push @$sf1,"-";
        }

    }
   
    foreach my $sf2(@$sfList2){
        next if(scalar(@$sf2)>2);
        push @$sf2,"+";

    }
}










