#!/usr/bin/perl

use strict;
use warnings;

use Carp qw(confess);
use Data::Dumper;
use File::Path;
use Getopt::Std;
use POSIX qw(ceil);
use XML::LibXML;

use Ernad::Erimp;
use Ernad::Common;
use Ernad::Dates;
#use Ernad::Sort;
use Ernad::Generate;
use Ernad::Sausage;
use Ernad::Yanabino;

binmode(STDOUT,":utf8");

## options
my %o;
getopts("ae:oNvd:s", \%o) or die;

## autopilot should be the default
my $auto_pilot=$o{'a'} // '1';

my $do_no_harvest=$o{'N'};

## allow for a multiplier
my $clear_excess=$o{'e'} // 0;

my $fake_date=$o{'d'} // '';
if($fake_date and not $fake_date=~m|\d{4}-\d{2}-\d{2}|) {
  print "I don't like your -d option $fake_date\n";
  exit;
}

my $impna=$ARGV[0] // '';
if(not $impna) {
  print "I need an impna.\n";
  exit;
}

our $e=Ernad::Erimp->new({'impna'=>$impna});

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

## no such argument in the crontab entry.  it is meant
## to give a manual size  target rather than the annual average
my $target_argument=$ARGV[1] // '';
my $target_number;
my $weekly_average=0;
my $count_papers_in_queue;
if($target_argument=~m|^\d+|) {
  if($target_argument=~m|^0|) {
    print "I can't take a target_argument starting with 0.\n";
    exit;
  }
  $target_number=$target_argument;
}
else {
  $weekly_average=&Ernad::Yanabino::find_weekly_average(365);
  if(not $target_argument) {
    $target_number=$weekly_average;
  }
  elsif($target_argument=~m|\.\d+$|) {
    $count_papers_in_queue=&Ernad::Yanabino::count_papers_in_queue;
    if($count_papers_in_queue < $weekly_average) {
      $target_number=$weekly_average;
    }
    else {
      my $gap=$count_papers_in_queue-$weekly_average;
      $target_number=$weekly_average+int($target_argument*$gap);
    }
  }
  else {
    print "I can't deal with your target_argument '$target_argument'.";
    exit;
  }
}

if($o{'v'}) {
  $count_papers_in_queue=&Ernad::Yanabino::count_papers_in_queue;
  print "count_paper_in_queue is $count_papers_in_queue\n";
}

my $piles_dir=$e->{'dir'}->{'pile'} // die "I don't see the pile_dir.";
my $issues_dir=$e->{'dir'}->{'issues'} // die "I don't see the issues_dir.";

my $issuedate=&Ernad::Dates::today();
if($fake_date) {
  $issuedate=$fake_date;
}
my $today_dir=$piles_dir.'/'.$issuedate;

## clear out today_dir
if($o{'o'}) {
  if($o{'v'} and -d $today_dir) {
    print "I delete $today_dir\n";
  }
  system("rm -rf $today_dir");
}
my $eles_fetched;
if(-d $today_dir and not $do_no_harvest) {
  print "I found $today_dir, use -o to overwrite\n";
  ## debug on 2025-11-24
  my $count=0;
  foreach my $fufi (glob("$today_dir/*.xml")) {
    print("I see $fufi\n");
    my $doc = XML::LibXML->load_xml(location=>$fufi, no_cdata=>1);
    my $xpc=$e->{'x'}->{'xpc'} // confess "I need an XPath context here.";
    foreach my $ele ($xpc->findnodes("/amf:amf/amf:collection/amf:haspart", $doc)->get_nodelist()) {
      $eles_fetched->[$count++] = $ele;
    }
  }
}
else {
  ## build files as in the normal script
  my $count_papers_to_be_fetched=$target_number;
  my $piles;
  if(not $do_no_harvest) {
    ## excess harvesting
    my $list_piles=&Ernad::Yanabino::list_piles($piles_dir);
    my $last_issuedate=&Ernad::Yanabino::find_last_issuedate_by_piles($list_piles);

    if($clear_excess) {
      $piles=&Ernad::Yanabino::get_piles($piles_dir);
      foreach my $date (keys %$piles) {
        if($o{'v'}) {
          print "for $date, I compare $date with $last_issuedate\n";
        }
        my $diff_date=&Ernad::Dates::diff_dates($date,$last_issuedate);
        if(not $diff_date > 0) {
          next;
        }
        my $file=$piles->{$date};
        my $count_total=&Ernad::Yanabino::count_handles_in_file($file);
        my $total_to_get_from_pile=int($clear_excess * $diff_date * $count_total / 365);
        my $out_file="$today_dir/$date.xml";
        if($o{'v'}) {
          print "For $file, diff_date is $diff_date.\n";
          print "I am getting $total_to_get_from_pile from $file as excess\n";
        }
        my $eles=&Ernad::Yanabino::trim_and_save_file($file,$out_file,$total_to_get_from_pile);
        foreach my $handle (keys %$eles) {
          push(@$eles_fetched,$eles->{$handle});
        }
      }
    }
    ## standard harvest
    ## while there is at least one paper to fetch
    $piles=&Ernad::Yanabino::get_piles($piles_dir);
    while($count_papers_to_be_fetched > keys %{$piles}) {
      ## this lists the lastest piles that still have papers
      my $piles=&Ernad::Yanabino::get_piles($piles_dir);
      ## get out if we don't have piles with papers any more
      my $total_piles=scalar keys %$piles or last;
      ## old way, and still documented: round down
      #my $total_to_get_from_pile=int($count_papers_to_be_fetched/$total_piles);
      ## 2017-10-16: round up
      my $total_to_get_from_pile=&ceil($count_papers_to_be_fetched/$total_piles);
      foreach my $date (keys %$piles) {
        my $file=$piles->{$date};
        my $out_file="$today_dir/$date.xml";
        my $eles=&Ernad::Yanabino::trim_and_save_file($file,$out_file,$total_to_get_from_pile);
        my $count_eles=keys %$eles;
        if($o{'v'}) {
          #print "I got $count_eles from $file\n";
        }
        foreach my $handle (keys %$eles) {
          push(@$eles_fetched,$eles->{$handle});
        }
        $count_papers_to_be_fetched -= $count_eles;
      }
    }
  }
}



# print("\n\n$is_there\n");

my $namf_doc=$e->{'x'}->issuedoc();
my $col_ele=$e->{'xpc'}->find('/amf:amf/amf:collection',$namf_doc)->[0];
foreach my $text_ele (@$eles_fetched) {
  $col_ele->appendChild($text_ele);
}
# $new_papers_doc->setDocumentElement($new_papers_root_ele);
$namf_doc=$e->{'x'}->de_itemize($namf_doc);
&Ernad::Sausage::inject($namf_doc);
my $fn = $e->{'f'}->by_date( $issuedate );
my $issue_file = "$issues_dir/$fn";
## was the output of tthe style sheet $out->toFile($issue_file,2) or die;
# my $issue_file;
my @issue_files=glob("$issues_dir/$today*");
if(scalar(@issue_files) > 1) {
  confess "I see more than one issue";
}

if(scalar(@issue_files) == 1) {
  $issue_file=$issue_files[0];
}
else {
  $namf_doc->toFile($issue_file,2) or die;
  system("gzip $issue_file");
  $issue_file.='.gz';
}

## 'do_wait' means that the process does *NOT* run in the background
my $params={};
## always wait!
$params->{'do_wait'}=1;

## dexis
$params->{'arg'}='nep';
## I think we better wait, even though the krikt
## is likely to take longer, and when it is done,
## dexis should be
$e->{'y'}->run('dexis',$params);

## krikts
$params->{'arg'}="$issuedate";
$e->{'y'}->run('krikt',$params);

## nafra, same params as for krikt
$e->{'y'}->run('nafra',$params);

## vemli, -c for class vemlis, -i for issuedate
$params->{'arg'}="-c -i $issuedate";
$e->{'y'}->run('vemli',$params);

## 2026-01-26
$params={};
$e->{'y'}->run('dexis',$params);

## class. It makes no sense to use run_class, because
## we would need detection when it has running
$params={};
## -v verbose and -c cache selection screen
$params->{'arg'}="$issuedate -v -c";
$e->{'y'}->run('class',$params);

## 2026-01-26
$params={};
$e->{'y'}->run('dexis',$params);

## this direcotory disappears
my $log_dir="/home/ernad/ernad/var/$impna/log/release";
if(not -d $log_dir) {
  mkpath($log_dir);
}

## refresh issuefile
# system("/home/ernad/bin/refresh_issue_file $issue_file");
$params={};
$params->{'arg'}="$issue_file";
$e->{'y'}->run('refresh_issue_file',$params);

## try to run dexis
$params={};
# $params->{'arg'}="$issue_file";
$e->{'y'}->run('dexis',$params);

## release
$params={};
$params->{'arg'}="$issue_file";
$e->{'y'}->run('release',$params);


exit;
