#!/usr/bin/perl

#use utf8;
use strict;
use CGI;

use Opals::Constant;
use Opals::Context;
use Opals::Template qw(
    tmpl_read
    tmpl_write
    tmpl_preference
    tmpl_rangedPageList

);
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
);
use  Opals::Utility qw(
    util_getXmlRecord
    util_restoreLiteral
);

use Opals::Session qw(
    SessionHdl_getSSID
);
use JSON;
my $dbh = Opals::Context->dbh();
END { $dbh->disconnect(); }

my $input=getInput();
my $cgi = CGI->new;
my $action = $input->{'action'};
my $param =  $input->{'param'};
my $pos =  $input->{'pos'}||0;
my $marcJson1="";
my $marcJson2="";
my($xml1,$xml2)=('','');
# [{"rid"=>$rid,bcList=>[]}];
my $ssid        = SessionHdl_getSSID($cgi);
my $ridBcList=getGERecFromSession($dbh,$pos); 
# ORGINAL MARC
my $rid=$ridBcList->{'rid'};
$xml1 =util_getXmlRecord($rid);
my $orgMarcJson =getMarcJsonOBj($xml1);

# NEW MARC
$xml2 =_editMarcRec($dbh,$action,$param,[$ridBcList]);
my $newMarcJson =getMarcJsonOBj($xml2);
getDiffField($orgMarcJson,$newMarcJson);

print "Content-type: text/plain\n\n";

my $rs={orgMarcJson=>$orgMarcJson,newMarcJson=>$newMarcJson};
print   to_json($rs,{pretty=>1});
#-------------------------------------------------------------------------------
sub getInput{
  my $in={};
  if ($ENV{'REQUEST_METHOD'} eq "POST") {
        my $json ="";
        while (<STDIN>) {
            $json .= $_;
        }
        $in = decode_json($json);
   }
   return $in;
}
############################################################
sub getGERecFromSession{
    my ($dbh,$recPos)=@_;
    my $ridBcList={};
    my $bcList=[];
    my ($rid) =$dbh->selectrow_array("select distinct rid from opl_sessionVar where ssid='$ssid' && var='ge_rid' limit $recPos,1");
    if($rid){
        $ridBcList={rid=>$rid,bcList=>[]};
        my $sth=$dbh->prepare("select barcode from opl_sessionVar where rid=? && ssid='$ssid' &&  var='ge_rid'");
        $sth->execute($rid);
        while(my ($bc)=$sth->fetchrow_array){
            push @{$ridBcList->{'bcList'}},$bc;
        }
    }
    return $ridBcList;

}
############################################################
#
sub _editMarcRec{
    my($dbh,$action,$param,$ridBcList)=@_;
    # $ridBcList {"rid":    , 
    #            "bcList": [bc1,bc2,...]}
    my $xml=undef;
    my $GE_FN_MAP={
        cpDataField      =>\&mxml_cpDatafield,
        datafieldReplace =>\&mxml_datafieldReplace,
        updateItemType   =>\&mxml_updateItemType,
        updateRecType    =>\&mxml_updateRecType,
        delDatafield     =>\&mxml_delDatafield,
        delSubfield      =>\&mxml_delSubfield,
        addSubfield      =>\&mxml_addSubfield,
        addDatafield     =>\&mxml_addDatafield,
        mvDatafield      =>\&mxml_mvDatafield,
        cpSubfield       =>\&mxml_cpSubfield,
        mvSubfield       =>\&mxml_mvSubfield,
        updateFieldInd   =>\&mxml_updateFieldInd
    };

    if(defined $GE_FN_MAP->{$action}){
        my $fn= $GE_FN_MAP->{$action};
        foreach my $item (@$ridBcList){
            my $rid=$item->{'rid'};
            my $bcList=$item->{'bcList'};
            $xml = util_getXmlRecord($rid) || next;
            $param->{'rid'}=$rid;
            $param->{'bcList'}=$bcList;
            $xml = &$fn($xml,$param);

#$xml =~ s/> </></g;

        }
    }
    return $xml;
}


################################################################################  
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);
        $ind1="#" if($ind1 eq ' ');
        $ind2="#" if($ind2 eq ' ');
        my @f=($tag,$ind1,$ind2);
        my @sfList=();
        while($sf =~s/<subfield code="(.?)">(.*?)<\/subfield>//){
            push @sfList,[$1,util_restoreLiteral($2)] if($1 ne '-');
        }
        push @f,\@sfList;
        push @fields,\@f;
    }
    $marc->{'fields'}=\@fields;
    return $marc;



}

################################################################################  
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,"+";

    }
}

   
################################################################################   
sub getDiffField{
    my ($marcJson1,$marcJson2)=@_;
    my $fields_1=$marcJson1->{'fields'};
    my $fields_2=$marcJson2->{'fields'};
    if($marcJson1->{'leader'} ne $marcJson2->{'leader'}){
        $marcJson1->{'leaderChanged'}=1;
        $marcJson2->{'leaderChanged'}=1;
    }
    my $match=0;
    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 '852' && @$f2[0]  eq '852' ){
            #    open debug,">/tmp/aa"; print debug to_json($f1) ."\n" .to_json($f2)." \n";close debug; 
            #}
            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,"+";
    }
}
  

