package SIP::Utility;

# Version number
$VERSION = 0.01;

use strict;
use LWP::UserAgent;
use MARC::Record;
use POSIX qw(
  ceil
  strftime
);

use Opals::Marc::Record;

use SIP::Map;

################################################################################
sub new {
  my $class = shift;
  my (%param) = (@_);

  my $this = {};

  bless $this, $class;

  #  $this->set(%param);

  return $this;
}

#############################################################
#sub init {
#  my $this = shift;
#
#  foreach my $k (keys %{$this}) {
#    delete $this->{$k} unless ($k eq 'dbh');
#  }
#}
#
#############################################################
#sub set {
#  my $this = shift;
#
#  return unless (@_);
#
#  my (%param) = (@_);
#
#  $this->init();
#  foreach my $k (keys %param) {
#    $this->{$k} = $param{$k};
#  }
#}

############################################################
sub format_datetime {
  my $this = shift;

  my ($datetime, $format) = @_;

  if ($format && $format eq 'SIP') {
    return _dateTime_SIP($datetime);
  }

  #default to ISO format
  return _dateTime_ISO($datetime);
}
############################################################

sub _dateTime_ISO {
  my ($sip_datetime) = @_;

  my $iso_datetime = $sip_datetime;
  $iso_datetime =~
s/([\d]{4})([\d]{2})([\d]{2}) {4}([\d]{2})([\d]{2})([\d]{2})/$1-$2-$3 $4:$5:$6/;

  return $iso_datetime;
}
############################################################

sub _dateTime_SIP {
  my ($ISO_datetime) = @_;

  my $SIP_datetime = $ISO_datetime;
  $SIP_datetime =~ s/[:\-]//g;
  $SIP_datetime =~ s/ /    /;

  return $SIP_datetime;
}
############################################################

sub getRecType {
  my $this = shift;

  my ($marc) = @_;

  my ($leader, $cf006, $cf007, $cf008) = ('', '', '', '');

  if ($marc->leader) {
    $leader = $marc->leader;
  }

  if ($marc->field('006')) {
    my @f = $marc->field('006');
    $cf006 = $f[0]->data();
  }

  if ($marc->field('007')) {
    my @f = $marc->field('007');
    $cf007 = $f[0]->data();
  }

  if ($marc->field('008')) {
    my @f = $marc->field('008');
    $cf008 = $f[0]->data();
  }

  my ($l_06, $l_07, $cf006_00, $cf007_00, $cf007_01, $cf008_23, $cf008_26) =
    ('', '', '', '', '');

  $l_06 = substr($leader, 6, 1);
  $l_07 = substr($leader, 7, 1);
  $cf006_00 = lc(substr($cf006, 0, 1)) if (length($cf006) > 0);
  $cf007_00 = lc(substr($cf007, 0, 1)) if (length($cf007) > 0);
  $cf007_01 = lc(substr($cf007, 1, 1)) if (length($cf007) > 1);

  $cf008_23 = lc(substr($cf008, 23, 1));
  $cf008_26 = lc(substr($cf008, 26, 1));

  my $recType = "book";

  # Journal ,serial
  if ($l_06 =~ m/[a]/ && $l_07 =~ m/[bis]/) {
    $recType = "journal";
  }

  # Book|eBook
  elsif ($l_06 =~ m/[t]/ || ($l_06 =~ m/[a]/)) {
    if ( $cf006_00 eq 'm'
      && $cf007_00 eq 'c'
      && $cf007_01 eq 'r'
      && $cf008_23 eq 's')
    {
      $recType = "ebook";
    }
    elsif ($l_07 =~ m/[acdm]/) {
      $recType = "book";
    }
  }

  # Artifact
  elsif ($l_06 =~ m/[r]/) {
    $recType = "artifact";
  }

  # Photos, Posters
  elsif ($l_06 =~ m/[k]/) {
    $recType = "photoPoster";
  }

  # Music Cassette
  elsif ($l_06 =~ m/[j]/) {
    $recType = "musicCassette";
  }

  # Book on Tape
  elsif ($l_06 =~ m/[i]/) {
    $recType = "bookOnTape";
  }

  # Movie
  elsif ($l_06 =~ m/[g]/) {
    $recType = "movie";
  }

  # Library Kit
  elsif ($l_06 =~ m/[o]/) {
    $recType = "libraryKit";
  }

  # Mixed Material
  elsif ($l_06 =~ m/[p]/) {
    $recType = "mixedMaterial";
  }

  # Map
  elsif ($l_06 =~ m/[ef]/) {
    $recType = "map";
  }

  # Sheet Music
  elsif ($l_06 =~ m/[cd]/) {
    $recType = "sheetMusic";
  }
  elsif ($l_06 =~ m/[m]/) {

    # Internet
    if ($cf008_26 =~ m/[j]/) {
      $recType = "internet";
    }

    # Electronic Media
    else {
      $recType = "electronicMedia";
    }
  }

  # CD Music
  elsif ($cf007_00 =~ m/[s]/ && $cf007_01 =~ m/[d]/) {
    $recType = "CDMusic";
  }

  # Compact Disc
  elsif ($cf007_00 =~ m/[c]/ && $cf007_01 =~ m/[o]/) {
    $recType = "compactDisc";
  }

  return $recType;

}
############################################################

sub getRecord {
  my $this = shift;

  my (%p) = (@_);

  my ($dbh, $barcode, $title) =
    ($p{'dbh'}, $p{'item_identifier'}, $p{'title_identifier'});

  my ($rid, @val);
  if ($barcode) {
    @val = ($barcode);
    ($rid) = $dbh->selectrow_array(<<_SQL_, undef, @val);
select  rid
from    opl_item
where   barcode = ?
_SQL_
  }
  elsif ($title) {
    @val = ($title);
    ($rid) = $dbh->selectrow_array(<<_SQL_, undef, @val);
select  rid
from    opl_record
where   title = ?
limit 1
_SQL_
  }

  my $xml = _getXmlRecord($rid) || return;
  my $marc = Opals::Marc::Record::newFromXml($xml);

  return $marc;
}
############################################################

sub _recordPath {
  my ($rid) = @_;

  my $zRoot     = Opals::Context->config('zRoot');
  my $zPort     = Opals::Context->config('zPort');
  my $zDatabase = Opals::Context->config('zDatabase');
  my $dir       = "$zRoot/$zPort/record/$zDatabase/" . ceil($rid / 1000);

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

sub _getXmlRecord {
  my ($rid) = @_;

  my $file = _recordPath($rid) . '/' . $rid . '.xml';

  if (!-r $file) {
    print "ERROR: $file not found/unreadable.\n";
    return;
  }

  my $record = '';
  open MARCXML, "<$file";
  while (<MARCXML>) {
    $record .= $_;
  }
  close MARCXML;

  return $record;
}
############################################################

sub getRecordInfo {
  my $this = shift;

  my (%p) = (@_);

  my $record = {
    type            => 'other',
    rid             => 0,
    title           => '',
    location        => '',
    collection_code => '',
    call_number     => '',
  };

  my $marc = $this->getRecord(%p) || return $record;

  $record->{'type'} = $this->getRecType($marc);
  (SIP::Map::MAP->{ $record->{'type'} }->{'magnetic_media'})
    || ($record->{'type'} = 'other');

  $record->{'rid'}      = $marc->field('001')->data();
  $record->{'title'}    = $marc->subfield('245', 'a');
  $record->{'location'} = $marc->subfield('852', 'b');

  my $barcode = $p{'item_identifier'};
  return $record unless $barcode;

  foreach my $f ($marc->field('852')) {
    if ($f->subfield('p') eq $barcode) {
      $record->{'collection_code'} = $f->subfield('c');

      foreach my $c (qw(k h i m)) {
        $record->{'call_number'} .=
          ($f->subfield($c)) ? ' ' . $f->subfield($c) : '';
      }
      $record->{'call_number'} =~ s/^ +//g;

      last;
    }
  }

  return $record;
}
############################################################

sub getLoan {
  my $this = shift;

  my ($dbh, $barcode) = @_;

  my @val = ($barcode);

  return $dbh->selectrow_hashref(<<_SQL_, undef, @val);
select  *
from    opl_loan
where   barcode = ?
     && dateReturn is null
_SQL_
}
############################################################

sub getItemType {
  my $this = shift;

  my ($dbh, $barcode, $uid) = @_;

  my @val = ($barcode, $uid);

  return $dbh->selectrow_hashref(<<_SQL_, undef, @val);
select  p.*
from    opl_item i 
        inner join opl_itemTypeParam p on i.typeId = p.itemTypeId
        inner join opl_user u on u.categorycode = p.userTypeId
where   i.barcode = ?
     && u.uid = ?
_SQL_
}
############################################################

sub now {
  return strftime('%F %T', localtime);
}
############################################################

sub post {
  my $this = shift;

  return unless (@_);

  my (%req) = @_;

  my $ua = LWP::UserAgent->new();
  $ua->agent($req{'ua'}        || 'OPALS SIP Client');
  $ua->timeout($req{'timeout'} || 120);

#  open LWP_POST, '>>/tmp/ctho-lwp-post';
#  print LWP_POST <<_LWP_POST_;
#url: $req{'url'}
#_LWP_POST_
#  close LWP_POST;

  return $ua->post($req{'url'}, Content => $req{'param'});
#  return $ua->post($req{'url'}, $req{'param'});

  #Content_Type => 'multipart/form-data',
}
############################################################

sub getPreference {
  my $this = shift;

  my ($dbh, $pref) = @_;

  my @val = ($pref);

  my ($value) = $dbh->selectrow_array(<<_SQL_, undef, @val);
select  val
from    opl_preference
where   var = ?
_SQL_

  return $value;
}

1;
