#!/usr/bin/perl

#use utf8;
use strict;
use CGI;

use Opals::Context;
use Digest::SHA qw(
  sha512_hex
);
use Date::Calc qw(Today Add_Delta_Days Day_of_Week Week_Number Day_of_Year);

use Opals::Template qw(
  tmpl_read
  tmpl_write
  tmpl_preference
);
use Opals::Search qw(
  srch_systemList
);

#use Opals::Marc21 qw(
#    mc21_getNumHoldingImport
#);
#
use Opals::Locale qw(
  loc_getMsgFile
  loc_write

);

use Opals::BarcodeMgmt qw(
  bcm_getBcRangeList
);

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

my $cgi   = CGI->new;
my $input = $cgi->Vars();
my ( $permission, $cookie, $template ) = tmpl_read(
    {
        dbh           => $dbh,
        cgi           => $cgi,
        tmplFile      => 'record/import.tmpl',
        reqPermission => 'marc_edit|marc_import',
    }
);

$dbh->do(<<_STH_);
delete from opl_marcImport
where   status ='uploaded' &&
        to_days(now()) - to_days(dateUpload) > 2
_STH_

my $sth;
my ( $mesgDigest, $iid, $fileDuplicated );

# Thu, Feb 26, 2009 @ 09:03:50 EST
my $syspref             = tmpl_preference($dbh);
my $autoAdd2NewItemList = $syspref->{'autoAdd2NewItemList'};
$autoAdd2NewItemList = 0 if ( $autoAdd2NewItemList !~ m/^0$|^1$/ );
my ( $year, $month, $day ) = Today();
( $year, $month, $day ) = Add_Delta_Days( $year, $month, $day, 90 );
my $defaultNewItemExpDate = sprintf( "%04d-%02d-%02d", $year, $month, $day );
my $newItemExpDate;
$newItemExpDate = $defaultNewItemExpDate if ( !$newItemExpDate );

#/

my $marc = $cgi->param('marc');
my ( $totalHolding, $totalHoldingWObc ) = ( 0, 0 );
if ( $marc && $ENV{'REQUEST_METHOD'} =~ m/post/i ) {
    my $lid = $input->{'lid'};
    my $sid = $input->{'sid'};

    #    ($lid) || ($lid = 0);

    my $uid      = $template->param('curUserId');
    my $encoding = $input->{'encoding'};
    ( $encoding eq 'MARC-8' ) || ( $encoding = 'UTF-8' );

    my $sf852Code = $input->{'sf852Code'};
    my $sf852Data = $input->{'sf852Data'};

    my $sf856Code = '';
    my $sf856Data = $input->{'sf856_3'};
    $sf856Data =~ s/^ | $//;
    if ( $sf856Data ne '' ) {
        $sf856Code = '3';
    }

    my $addToNewItemList = $input->{'addToNewItemList'};
    $addToNewItemList = 0 if ( !$addToNewItemList || $addToNewItemList != 1 );
    $newItemExpDate = $input->{'newItemExpDate'};

    my $recType = $input->{'recordType'};
    ($recType) || ( $recType = 'hardCopy' );

    my $mode = $input->{'mode'};
    ($mode) || ( $mode = 'autoMerge' );

#    my $mergeMode = $input->{'mergeMode'};
#    ($mergeMode) || ( $mergeMode = 'strict' );

    my $holding_op = $input->{'holding_op'};
    ($holding_op) || ( $holding_op = 'update' );

    my $recordSource = $input->{'recordSource'};
    ($recordSource) || ( $recordSource = $cgi->cookie('recordSource') ) || ( $recordSource = 'generic_loose' );

    $recordSource =~ s/_(strict|loose|re-import)$//;
    my $mergeMode = $1;
    $template->param(mergeMode =>$mergeMode);


    my $marcFile = '';
    while (<$marc>) {
        $marcFile .= $_;
    }
    my @mRec = split( /\x1D/, $marcFile );
    $marcFile = '';
    foreach my $rec (@mRec) {
        if ( length($rec) > 24 ) {
            $marcFile .= "$rec\x1D";
            substr( $rec, 9, 1, ' ' );
            $rec .= "\x1D";
            my $marc = MARC::File::USMARC->decode( $rec, \&mc21_filter );
            if ( scalar( $marc->field('852') ) == 0 ) {
                $totalHoldingWObc++;
                $totalHolding++;
                next;
            }
            foreach my $f852 ( $marc->field('852') ) {
                my $tmpBc = $f852->subfield('p');
                $tmpBc =~ s/^\s*//gs;
                $totalHoldingWObc++ if ( $tmpBc eq '' );
                $totalHolding++;
            }

        }
    }

    $mesgDigest = sha512_hex($marcFile);
    @mRec = split( /\x1D/, $marcFile );
    my $countTotal = $#mRec + 1;

    $addToNewItemList = 0 if ( $countTotal > 300 );

    # Always insert uploaded data with invalid status.
    $sth = $dbh->prepare(<<_STH_);
insert into opl_marcImport
set sid         = $sid,
    lid         = $lid,
    uid         = $uid,
    encoding    = ?,
    sf852Code   = ?,
    sf852Data   = ?,
    sf856Code   = ?,
    sf856Data   = ?,
    type        = ?,
    mode        = ?,
    mergeMode   = ?,
    countTotal  = $countTotal,
    dateUpload  = now(),
    addToNewitemList = ?,
    newItemExpDate = ?,
    mesgDigest  = ?,
    holding_op  = ?,
    recordSource= ?
_STH_
    $sth->execute(
        $encoding,       $sf852Code,  $sf852Data,
        $sf856Code,      $sf856Data,  $recType,
        $mode,           $mergeMode,  $addToNewItemList,
        $newItemExpDate, $mesgDigest, $holding_op,
        $recordSource
    );

    #$sth->execute($mesgDigest, $marcFile);
    $sth->finish();
    $template->param( newItemExpDate => '2009-10-12' );

    # Get iid for latest uploaded data with invalid status. All other previous
    # uploads with invalid status are ignored.
    $sth = $dbh->prepare(<<_STH_);
select  iid
from    opl_marcImport
where   mesgDigest = ? &&
        status = 'uploaded'
order by dateUpload desc
limit 1
_STH_
    $sth->execute($mesgDigest);
    ($iid) = $sth->fetchrow_array;

    my $db_name = Opals::Context->config('db_name');
    my $imex    = Opals::Context->config('imex');
    open FILEIMPORT, ">$imex/import/$db_name/$iid";
    print FILEIMPORT $marcFile;
    close FILEIMPORT;

    # Check if file has been uploaded
    $sth = $dbh->prepare(<<_STH_);
select  count(*)
from    opl_marcImport
where   mesgDigest = ?
_STH_

    #     && status in ('accepted','indexing','done')
    $sth->execute($mesgDigest);
    ($fileDuplicated) = $sth->fetchrow_array;
    $sth->finish();

    if ( $fileDuplicated && $fileDuplicated > 1 ) {
        $template->param(
            fileDuplicated => 1,
            iid            => $iid,
        );
    }

    #    else {
    #        $template->param(
    #            fileUploaded => validateUpload($dbh, $iid),
    #        );
    #    }
}

if ( $input->{'iid'} && $ENV{'REQUEST_METHOD'} =~ m/post/i ) {
    if ( $input->{'imDup'} == 1 ) {
        $template->param(
            fileUploaded => validateUpload( $dbh, $input->{'iid'} ), );
    }
    elsif ( $input->{'imAccepted'} eq 'accept' ) {
        $template->param( fileUploaded => acceptUpload( $dbh, $input->{'iid'} ),
        );
    }
    else {    # reject new or duplicated import
        $template->param( fileDeleted => rejectUpload( $dbh, $input->{'iid'} ),
        );
    }
}

my $catType = Opals::Context->config('type');

#Thu, Jul 08, 2010 @ 08:41:39 EDT
#my ($totalHolding,$totalHoldingWObc) = mc21_getNumHoldingImport($iid);
$template->param(
    totalHolding     => $totalHolding,
    totalHoldingWObc => $totalHoldingWObc,
    iid              => $iid,
);

my @importInfo;
$sth = $dbh->prepare(<<_STH_);
select  m.*, 
        u.uid, u.firstname, u.lastname, 
        (countTotal - countProcessed) as countImporting
from    opl_marcImport as m left outer join opl_user as u on m.uid = u.uid
order by iid desc
_STH_

#where   m.status in ('accepted','indexing','done')
$sth->execute();

my $sth_lidInfo = $dbh->prepare(<<_STH_);
select  s.sid, s.sCode, s.sName,
        l.lid, l.lCode, l.lName
from    opl_libSystem as s, opl_library as l
where   l.lid   = ?
     && s.sCode = l.sysCode
_STH_

my $sth_mergeCount = $dbh->prepare(<<_STH_);
select  count(*)
from    opl_marcDuplicate
where   iid = ?
_STH_

my $rec_src = {
    generic_strict => 'generic',
    OCoLC_loose => 'OCoLC',
    generic_loose => 're-import',
};

while ( my $iInfo = $sth->fetchrow_hashref ) {
    if ( $mesgDigest && $mesgDigest eq $iInfo->{'mesgDigest'} ) {
        $iInfo->{'duplicated'} = 1;
    }

    if ($catType) {
        $sth_lidInfo->execute( $iInfo->{'lid'} );
        my $libInfo = $sth_lidInfo->fetchrow_hashref;
        $iInfo->{'sid'}   = $libInfo->{'sid'};
        $iInfo->{'sCode'} = $libInfo->{'sCode'};
        $iInfo->{'sName'} = $libInfo->{'sName'};
        $iInfo->{'lid'}   = $libInfo->{'lid'};
        $iInfo->{'lCode'} = $libInfo->{'lCode'};
        $iInfo->{'lName'} = $libInfo->{'lName'};
    }

    $sth_mergeCount->execute( $iInfo->{'iid'} );
    ( $iInfo->{'countPending'} ) = $sth_mergeCount->fetchrow_array;
    if ( $iInfo->{'countTotal'} == $iInfo->{'countProcessed'} ) {
        $iInfo->{'countIgnored'} =
          $iInfo->{'countTotal'} -
          $iInfo->{'countImported'} -
          $iInfo->{'countMerged'} -
          $iInfo->{'countPending'};
    }
    else {
        $iInfo->{'countIgnored'} = 0;
    }

    $iInfo->{ 'recInStatus_' . $iInfo->{'status'} } = 1;

    $iInfo->{'recordSource'} = 
        $rec_src->{$iInfo->{'recordSource'}.'_'.$iInfo->{'mergeMode'}};

    push @importInfo, $iInfo;
}

$sth->finish;
$sth_lidInfo->finish;
$sth_mergeCount->finish;

$template->param( importInfo => \@importInfo, );

if ($autoAdd2NewItemList) {
    $template->param(
        autoAdd2NewItemList => $autoAdd2NewItemList,
        newItemExpDate      => $newItemExpDate,

    );
}

if ($catType) {
    $template->param( systemList => srch_systemList($dbh), );
}
# GET LIST OF LOCATIONS
   my $locationList = getLocationList($dbh,$input->{'location'});
   $template->param(  locList=>$locationList);
# GET LIST OF ITEM TYPE FROM opl_itemType TABLE
    my $itemTypeList = getItemTypeList($dbh);
    $template->param(itemTypeList =>  $itemTypeList);
# GET LIST OF PREFIX 852 k
    my $prefixList =  getPrefixList($dbh);
    $template->param(prefixList =>  $prefixList);



my $importMsgMap     = loc_getMsgFile('item/import.msg');
my $marc21EditMsgMap = loc_getMsgFile('marc21/edit.msg');
loc_write( $template, $importMsgMap );
loc_write( $template, $marc21EditMsgMap );
$template->param( hlpUrl => Opals::Constant->getHlpUrl('import') );

#if ($permission && $permission->{'marc_edit'}) { $template->param(marc_edit => 1); }
tmpl_write( $dbh, $cgi, $cookie, $template );

#$dbh->disconnect();
################################################################################

sub acceptUpload {
    my ( $dbh, $iid ) = @_;

    my $rv = $dbh->do(<<_STH_);
update  opl_marcImport
set     status = 'accepted',
        dateUpload = now()
where   iid = $iid
_STH_

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

sub validateUpload {
    my ( $dbh, $iid ) = @_;

    my $rv = $dbh->do(<<_STH_);
update  opl_marcImport
set     status = 'uploaded',
        dateUpload = now()
where   iid = $iid
_STH_

    return $rv;
}

############################################################

#sub deleteUpload {
#    my ($dbh, $iid) = @_;
#
#    my $rv = $dbh->do(<<_STH_);
#delete from opl_marcImport
#where   iid = $iid
#_STH_
#
#    my $db_name = Opals::Context->config('db_name');
#    my $imex    = Opals::Context->config('imex');
#    unlink "$imex/import/$db_name/$iid";
#
#    return $rv;
#}
############################################################

sub rejectUpload {
    my ( $dbh, $iid ) = @_;

    my $rv = $dbh->do(<<_STH_);
update  opl_marcImport
set     status = 'rejected'
where   iid = $iid
_STH_

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

sub mc21_filter {
    my ( $tagno, $tagdata ) = @_;

    return
         ( length($tagno) == 3 )
      && ( $tagno !~ m/[\D]/ )
      && ( $tagno ne '005' )
      && ( $tagno < 900 || $tagno == 940 );

    #           ($tagno ne '001') &&
}
################################################################################     
sub getPrefixList{
    my ($dbh)= @_;
    my $sql = <<_SQL_;
select distinct trim(sfData) sf852Data from opl_authCtrl where sfCode='k' order by sfData
_SQL_

    my $sth = $dbh->prepare($sql);
    $sth->execute();
    my @retVal;
    while (my $loc = $sth->fetchrow_hashref) {
        push @retVal, $loc;
    }
    $sth->finish;
           
    return \@retVal;
}

#=======================================================
sub getLocationList{
    my($dbh,$curSrchLoc)=@_;
    my $locList=[];
    my $sth=$dbh->prepare("select distinct trim(sfData) from opl_authCtrl where sfCode='c' order by sfData");
    $sth->execute();
    while(my  ($location) =$sth->fetchrow_array){
        my $selected=($curSrchLoc eq $location);
        push @$locList,{location=>$location,selected=>$selected};
    }
    return $locList;
}
################################################################################     
sub getItemTypeList{
    my ($dbh)= @_;
    my $sql = <<_SQL_;
SELECT     distinct id 
FROM       opl_itemType
WHERE      id <>""
ORDER BY    id
_SQL_

    my $sth = $dbh->prepare($sql);
    $sth->execute();
    my @retVal;
    my $itentypeStr=""; 
    while (my $id = $sth->fetchrow_hashref) {
          push @retVal, $id;
    }
    $sth->finish;
           
    return \@retVal;
}

