#!/usr/bin/perl

## make sure we can run this from bims via sudo from pubmed
use lib qw(/home/ernad/ernad/perl /home/ernad/usr/share/perl /home/ernad/lib/perl);

use strict;
use warnings;

use Carp qw(confess);
use Data::Dumper;
use Sys::RunAlone;
use Getopt::Std;

use Ernad::Args;
use Ernad::Adverts;
use Ernad::Constant;
use Ernad::Common;
use Ernad::Dates;
use Ernad::Erimp;
use Ernad::Issues;
use Ernad::Namf;
use Ernad::Notify;
use Ernad::Presort::Seeds;
use Ernad::Presort::Dates;
use Ernad::Presort;
use Krichel::File;

my %options;
&getopts('utfx:r:nv:', \%options);

my $do_only_unsorted=$options{'u'} // '';
## do only one repcode
my $only_do_repcode=$options{'r'} // '';
my $exclude_repcode=$options{'x'} // '';
my $do_testing=$options{'t'};
my $dont_truncate=$options{'f'};
## disable counting of texts in rif at the start, this takes
## a lot of time
my $dont_count=$options{'n'} // '';
my $do_verbose=$options{'v'} // 2;


our ($impna, $e, $repcode, $in_file);
## overwrite files that exist?
$in_file=$ARGV[0];
if(not $in_file) {
  print "I need a namf file here.\n";
  exit;
}
if(not -f $in_file) {
  print "I can't open the naf $in_file.";
  exit;
}

&Ernad::Args::parse();
$e=Ernad::Erimp->new({'impna'=> $impna, 'verbose'=>3});

## to keep old variable naming
my $naf=$in_file;
if(not $dont_count and not $e->{'x'}->count_texts($naf)) {
  print "I don't see any texts in your naf $naf\n";
  exit;
}

my $namf=$Ernad::Constant::c->{'namf_dir'}
   or confess "You have not defined a namf_dir name.";
my $allport_repcode = $e->get_allport_repcode() // '';
if($allport_repcode) {
  my $allport_sent="$allport_repcode/sent";
  if(not $naf=~m|/$allport_sent/|) {
    confess "Your file $naf is not an allport_sent file.";
  }
}
elsif(not $naf=~m|/$namf/|) {
  confess "Your file $naf is not a namf file.";
}

## check for a holiday
my $today=&Ernad::Dates::today();
my $holiday_regex=$e->{'conf'}->{'holidays'} // '';
if($holiday_regex and $today=~m|$holiday_regex| and not $do_testing) {
  $e->echo(__LINE__,"Today, $today, is a holiday. I relax.");
  exit;
}

## I always test on the test machine
if($e->{'testing'}) {
  $do_testing=1;
}

## fixme:: to go in 2019
our $issuedate=&Ernad::Presort::Dates::set_issuedate($naf,$do_testing);
$e->{'file'}->{'namf'}=$naf;

my $unleasher = sub {
  ## this is handed by the caller
  my $repcode=shift;
  ## reset key
  $e->{'repcode'}='';
  $e->{'issuedate'}='';
  $e->{'namf'}='';
  ## maybe put ahead
  if($dont_truncate) {
    $e->{'conf'}->{'truncate'}=0;
  }
  if($only_do_repcode and $only_do_repcode ne $repcode) {
    $e->echo(__LINE__,"I skip $repcode.",10);
    return 0;
  }
  if($exclude_repcode and $exclude_repcode eq $repcode) {
    $e->echo(__LINE__,"I skip $repcode.",10);
    return 0;
  }
  $e->{'repcode'}=$repcode;
  $e->{'issuedate'}=$issuedate;
  my $rerc=$e->{'report'}->{$repcode};
  if(not $e->{'report'}->{$repcode}) {
    ## this is temporary for non-Osborne
    if($e->{'r'}) {
      $e->{'r'}->load($repcode);
    }
  }
  my $namf=shift;
  $e->echo(__LINE__,"I'm looking at $repcode for work to do.");
  $e->echo(__LINE__,"I have to do $repcode $issuedate $naf.");
  ## up there is the wrong issuedate
  # die $issuedate;
  ## saves to report in the next module
  $e->{'repcode'}=$repcode;
  $e->{'issuedate'}=$issuedate;
  $e->{'namf'}=$namf;
  ## done in a hasty for NEP 2019-01-05
  #my $us_rif=&create_unsorted($repcode,$issuedate,'keep');
  #if($do_only_unsorted) {
  #  return 0;
  #}
  $e->echo(__LINE__,"I presort for $repcode.",1);
  my $ps_rif=&Ernad::Presort::presort($repcode,$issuedate,$namf);
  if(not $ps_rif) {
    return 0;
  }
  &Ernad::Adverts::inject_adverts_into_rif($ps_rif,$e);
  $e->echo(__LINE__,"I placed adverts into $ps_rif.");
  &Ernad::Notify::notify($e,$ps_rif);
};


## build cache for the selection screen
my $cache_selection_screen= sub {
  ## this is handed by the caller
  my $repcode=shift;
  ## reset key
  $e->{'repcode'}='';
  $e->{'issuedate'}='';
  $e->{'namf'}='';
  my $rerc=$e->{'report'}->{$repcode};
  if($only_do_repcode and $only_do_repcode ne $repcode) {
    $e->echo(__LINE__,"I skip $repcode.",10);
    return 0;
  }
  $e->{'repcode'}=$repcode;
  ## global variable
  $e->{'issuedate'}=$issuedate;
  my $namf=shift;
  my $cache_dir=$e->{'report'}->{$repcode}->{'dir'}->{'cache'} //
    confess "I need the cache_dir defined here.";
  my $cc_dir=$cache_dir.'/'.$e->{'const'}->{'created_dir'};
  my $cache_file=$cc_dir."/$issuedate.html";
  &Krichel::File::prepare($cache_file);
  ## fixme:: add some checks of it being newer that the namf file
  ## fixme ... I just made this up
  my $params= {'back_from' => "'source'",
               'stage' => "'created'",
               'Report' => "'$repcode'",
               'repcode' => "'$repcode'"};
  my $ps_dir=$rerc->{'dir'}->{'presorted'} // confess "Where is my presorted_dir?";
  ## ps_file file first
  #my $ps_file=$ps_dir.'/'.&Ernad::Common::get_most_recent_rif($ps_dir,'lax',$issuedate);
  my $ps_bana=$e->{'d'}->most_recent_rif($ps_dir,'lax',$issuedate);
  if(not $ps_bana) {
    $e->echo(__LINE__,"I can not cache the selection screen for $repcode.");
    return 0;
  }
  my $ps_file=$ps_dir.'/'.$ps_bana;
  ## if this does not exist,
  if(not -f $ps_file) {
    $ps_file=$e->{'d'}->most_recent_rif($ps_dir,'lax',$issuedate);
  }
  if(not -f $ps_file) {
    $e->echo(__LINE__,"I don't see your ps_file $ps_file");
  }
  if(not $e->{'d'}->most_recent_rif($ps_dir,'lax',$issuedate)) {
    $e->echo(__LINE__,"I have no rif in $ps_dir and issuedate $issuedate");
    return 0;
  }
  #if(not $e->{'d'}->most_recent_rif($ps_dir,'lax',$issuedate)) {
  #  $e->echo(__LINE__,"I have no rif in $ps_dir and issuedate $issuedate");
  #}
  if($ps_file) {
    if(not &Ernad::Files::does_file_need_renewal($cache_file,$ps_file)) {
      $e->echo(__LINE__,"$cache_file needs no renewing over $ps_file.");
      return 0;
    }
    if(-d $ps_file) {
      return 0;
    }
    if(not $ps_file=~m|$issuedate|) {
      $e->echo(__LINE__,"I found '$ps_file'. It does not match my issuedate '$issuedate'.");
      return 0;
    }
    $e->echo(__LINE__,"I found $ps_file. I start to transform papers_screen...");
    my $doc=$e->{'t'}->transform_file($ps_file,'papers_screen',$params);
    $doc->toFile($cache_file);
    $e->echo(__LINE__,"I'm wrote $cache_file.");
    return 1;
  }
  $e->echo(__LINE__,"I should not be here.");
};

## main call
#$e->call_on_all_reports($unleasher,$naf,$only_do_repcode);
#$e->call_on_all_reports($cache_selection_screen,$naf);
$e->{'o'}->call_by_lafise($unleasher,$naf,$only_do_repcode);
$e->{'o'}->call_on_all_reports($cache_selection_screen,$naf);

exit;

## make this work with NEP to create an unsorted report


sub create_unsorted {
  my $repcode = shift // confess "I want a repcode here.";
  my $issuedate= shift // confess "I want an issuedate here.";
  my $o_k_n=shift;
  if(not defined($o_k_n)) {
    confess "The o_k_n parameter is missing on create_unsorted.";
  }
  if(($o_k_n ne 'overwrite')
     and ($o_k_n ne 'keep')
     and ($o_k_n ne 'no_write')) {
    confess 'o_k_n has to be overwrite or keep or no_write';
  }
  if(not ($o_k_n eq 'no_write')) {
    if($e->{'s'}->is_futile($repcode,$issuedate)) {
      return 0;
    }
  }
  if($o_k_n eq 'keep') {
    my $rerc=$e->{'report'}->{$repcode};
    if(not $rerc) {
      $e->{'r'}->load($repcode);
    }
    $rerc=$e->{'report'}->{$repcode};
    if(not $rerc) {
      confess "I don't get the report data for $repcode.";
    }
    my $us_dir= $rerc->{'dir'}->{'unsorted'} or die;
    my $us_rif_glob="$us_dir/*$issuedate*";
    my @files=glob($us_rif_glob);
    if(scalar @files) {
      my $us_rif=$files[$#files];
      $e->echo(__LINE__,"There is an unsorted file $us_rif, I won't make a new one.",1);
      #$l->{'us_rif'}=$us_rif;
      #$l->{'unsorted_doc'}=&Krichel::File::load($us_rif);
      return 1;
    }
  }
  ## checked wether we have issuedate and repcode sete.
  #$l->check_dapor();
  my $allport_dom=$e->{'allport_dom'};
  if(not $allport_dom) {
    $e->echo(__LINE__,"I read the namf file $naf.");
    $e->{'allport_dom'}=&Krichel::File::load($naf);
    $allport_dom=$e->{'allport_dom'};
  }
  my $xpc=$e->{'xpc'};
  ## Createe a report issue from allport issue
  ## first, set report id
  my $rerc=$e->{'report'}->{$repcode} or confess "no rerc";
  my $repdoc=$rerc->{'repdoc'} or die;
  #my $to_string=$repdoc->toString();
  #$l->{'e'}->echo(__LINE__,"here is repdoc\n$to_string");
  my $report_id=$rerc->{'id'} // '';
  my $report_issue_handle = '';
  if($report_id) {
    $report_issue_handle = $report_id.":".$issuedate;
  }
  my $amf_element=$repdoc->documentElement();
  #my $collection_element=&Ernad::Common::get_collection_element($repdoc);
  my $collection_element=$e->{'x'}->collection_element($repdoc);
  if($report_issue_handle) {
    $collection_element->setAttribute( 'id', $report_issue_handle );
  }
  ## add the issue date to the data
  my $issuedate_element=$allport_dom->createElementNS($e->{'const'}->{'ernad_ns'},'issuedate');
  $issuedate_element->appendText($issuedate);
  $collection_element->appendChild($issuedate_element);
  ## issue advert, should be handled by Ernad::Adverts
  ## tihs assumes it is in the allport issue. This is not done automatically
  my $advert=$e->{'xpc'}->find('//e:advert',$allport_dom)->get_node(1) // '';
  if($advert) {
    $collection_element->appendChild($advert);
  }
  my $texts_xp='/amf:amf/amf:collection[1]/amf:haspart';
  my @hasparts=$xpc->findnodes($texts_xp,$allport_dom)->get_nodelist();
  foreach my $haspart_ele (@hasparts) {
   $collection_element->appendChild($haspart_ele);
  }
  ## remove existing ones if set to overwrite
  #  my $amf_doc=$e->get_amf_doc();
  my $amf_doc=$e->{'x'}->amf_doc();
  $amf_element=$amf_doc->documentElement();
  $amf_element->appendChild($collection_element);
  my $unsorted_doc=$amf_doc;
  #$amf_doc->toFile('/tmp/o.xml');
  if($o_k_n eq 'no_write') {
    $e->echo(__LINE__,"I give up on creating an unsorted issue because I have no_write set");
    return;
  }
  ## Save report to unsorted
  my $source_dir = $rerc->{'dir'}->{'source_dir'};
  my $us_dir= $rerc->{'dir'}->{'unsorted'} or die;
  my $us_rif=$us_dir.'/'.$e->{'f'}->by_date($issuedate);
  $e->echo(__LINE__,"Copying allport issue to $us_rif.",1);
  ## transit: change the unsorted report issue document, mainly to
  ## address futli report pointers
  my $transit_xslt_file=$e->{'dir'}->{'style'}.'/transit'.$e->{'const'}->{'xsl_ext'};
  if(-f $transit_xslt_file) {
    $amf_doc=$e->{'t'}->transform($amf_doc,'transit');
  }
  $amf_doc->toFile($us_rif,1);
  $e->echo(__LINE__,"I write $us_rif.");
  if($o_k_n eq 'overwrite') {
    &delete_already_there('unsorted',$repcode,$issuedate);
  }
  ## not yet implemented
  &Ernad::Adverts::inject_adverts_into_rif($us_rif,$e);
  $e->echo(__LINE__,"I placed adverts into $us_rif.");
}

sub delete_already_there {
  my $us_ps=shift;
  my $repcode=shift;
  my $issuedate=shift;
  ## except the file, to delete all others after creation
  my $except=shift // '';
  if(($us_ps ne 'unsorted') and ($us_ps ne 'presorted')) {
    die 'us_ps has to be unsorted or presorted.';
  }
  $e->echo(__LINE__,"I delete $repcode $issuedate $us_ps except $except",1);
  my $rerc=$e->{'report'}->{$repcode};
  if(not $e->{'report'}->{$repcode}) {
    ## this is temporary for non-Osborne
    if($e->{'r'}) {
      $e->{'r'}->load($repcode);
    }
  }
  my $dir=$rerc->{'dir'}->{$us_ps} or confess "I need this here.";
  my @already_there_files=glob("$dir/$issuedate*");
  foreach my $file (@already_there_files) {
    if($except and $file eq $except) {
      $e->echo(__LINE__,"I keep except $file",3);
      next;
    }
    $e->echo(__LINE__,"I remove $file",3);
    unlink $file;
  }
}



# sub delete_already_there {
#  my $l=shift;
#  my $us_ps=shift;
#  ## except the file, to delete all others after creation
#  my $except=shift // '';
#  if(($us_ps ne 'unsorted') and ($us_ps ne 'presorted')) {
#    die 'us_ps has to be unsorted or presorted.';
#  }
#  $l->check_dapor();
#  $l->{'e'}->echo(__LINE__,"I delete $repcode $issuedate $us_ps except $except",1);
#  my $rerc=$l->{'rerc'} or die "I need the allport_dom here.";
#  my $dir=$rerc->{'dir'}->{$us_ps} or die;
#  my @already_there_files=glob("$dir/$issuedate*");
#  foreach my $file (@already_there_files) {
#    if($except and $file eq $except) {
#      $l->{'e'}->echo(__LINE__,"I keep except $file",3);
#      next;
#    }
#    $l->{'e'}->echo(__LINE__,"I remove $file",3);
#    unlink $file;
#  }
#}
#
#sub is_already_there {
#  my $l=shift;
#  my $us_ps=shift;
#  if(($us_ps ne 'unsorted') and ($us_ps ne 'presorted')) {
#    die 'us_ps has to be unsorted or presorted.';
#  }
#  ## do we have report and issuedate set
#  $l->check_dapor();
#  my $rerc=$l->{'rerc'} or die "I need the allport_dom here.";
#  my $dir=$rerc->{'dir'}->{$us_ps} or die;
#  my @already_there_files=glob("$dir/$issuedate*");
#  foreach my $file (@already_there_files) {
#    my $fufi="$file";
#    $l->{'e'}->echo(__LINE__,"I found $fufi");
#  }
#  if(scalar(@already_there_files)) {
#    return 1;
#  }
#  return 0;
#}
#
#sub presort_ahead {
#  my $l=shift;
#  my $repcode=shift or confess "I need a repcode here.";
#  my $o_k_n=shift // 'keep';
#  my $fitport=&Ernad::Learn::Common::get_fitport($l,$repcode);
#  if(not defined($l->{'m'}->{$fitport})) {
#    $l->{'m'}->{$fitport}=Ernad::Learn::Dokli->new({'impna' => $l->{'impna'},
#                                                    'e'=> $l->{'e'},
#                                                    'verbose'=> $l->{'verbose'}});
#  }
#  my $m=$l->{'m'};
#  if(not defined($m->{'issuedates'})) {
#    $m->set_issuedates;
#    if(not defined($m->{'issuedates'})) {
#      confess "I can't find issuedates";
#    }
#  }
#  $l->set_report($repcode);
#  $l->set_dates_to_learn();
#  my $model_file=$l->{'m'}->find_most_recent_model($repcode);
#  if(not $model_file) {
#    $l->{'e'}->echo(__LINE__,"I have no model for $repcode. I start to build one.");
#    $l->{'m'}->model_report($repcode);
#    $model_file=$m->find_most_recent_model($repcode);
#    ## still not model file
#    if(not $model_file) {
#      $l->{'e'}->echo(__LINE__,"I can't get a model for $repcode, therefore presort_ahead fails.");
#
#      my @sortable_issues=keys %{$l->{'all_sortable_issues_for_report'}};
#      my $total_sortable_issues=scalar @sortable_issues;
#      if(not $total_sortable_issues) {
#        $l->{'e'}->echo(__LINE__,"I have no sortable issue for this report.");
#        $l->{'e'}->echo(__LINE__,"Looks like a virgin report.");
#        $l->{'e'}->echo(__LINE__,"I use the last allport issue as a fallback.");
#        my $dates=$l->{'e'}->get_available_issuedates();
#        my @sorted_dates=sort keys %$dates;
#        my $last_date=pop @sorted_dates;
#        $l->{'e'}->echo(__LINE__,"My last available allport issuedate is $last_date.");
#        ## hopefully changing that state var will not cause problems
#        push(@sortable_issues,$last_date);
#      }
#      ## still create unsorted ahead
#      foreach my $issuedate (sort @sortable_issues) {
#        $l->{'e'}->echo(__LINE__,"I create unsorted $repcode for $issuedate.");
#        $l->set_issuedate($issuedate);
#        $l->{'e'}->echo(__LINE__,"Done setting the issuedate $issuedate.");
#        $l->create_unsorted('keep');
#        $l->{'e'}->echo(__LINE__,"Done creating the unsorted.\n\n;");
#      }
#      return 0;
#    }
#  }
#  my $presorted_something=0;
#  my $ps_rif;
#  foreach my $issuedate (sort keys %{$l->{'all_sortable_issues_for_report'}}) {
#    $l->{'e'}->echo(__LINE__,"I presort $repcode for $issuedate.");
#    $l->set_issuedate($issuedate);
#    $l->{'e'}->echo(__LINE__,"Done setting the issuedate $issuedate.");
#    $ps_rif=$l->create_presorted('overwrite');
#    $l->{'e'}->echo(__LINE__,"Done creating the presorted.");
#    $presorted_something=1;
#  }
#  if(not $presorted_something) {
#    $l->{'e'}->echo(__LINE__,"I found no issues to presort.");
#  }
#  delete $l->{'unsorted_doc'};
#  delete $l->{'presorted_doc'};
#  return $ps_rif;
#}
#
#
## sub wipe_report {
##   my $l=shift;
##   my $repcode=shift or confess "I need a repcode here.";
##   my $fitport=&Ernad::Learn::Common::get_fitport($l,$repcode);
##   if(not defined($l->{'m'}->{$fitport})) {
##     $l->{'m'}->{$fitport}=Ernad::Learn::Dokli->new({'impna' => $l->{'impna'}});
##   }
##   my $m=$l->{'m'};
##   if(not defined($f->{'issuedates'})) {
##     $m->set_issuedates();
##     if(not defined($m->{'issuedates'})) {
##       confess "I can't find issuedates";
##     }
##   }
##   $l->set_report($repcode);
##   my @issuedates=keys %{$m->{'issuedates'}};
##   foreach my $issuedate (@issuedates) {
##     $l->set_issuedate($issuedate);
##     print "clearing work for $issuedate\n";
##     $l->clear_work('with_source');
##   }
## }
#
#
##sub initialize_report {
##  my $l=shift;
##  my $repcode=shift or confess "I need a repcode here.";
##
##  my $f=$l->{'f'};
##
##  my $f=$l->{'f'};
##  if(not defined($f->{'issuedates'})) {
##    $f->set_issuedates();
##    if(not defined($f->{'issuedates'})) {
##      confess "I can't find issuedates";
##    }
##  }
##  $l->set_report($repcode);
##  my @issuedates=keys %{$f->{'issuedates'}};
##  foreach my $issuedate (@issuedates) {
##    $l->set_issuedate($issuedate);
##    if($l->is_futile()) {
##      next;
##    }
##    print "setting for $issuedate\n";
##    $l->create_unsorted('overwrite');
##  }
##}

__END__

1;
