#!/usr/bin/perl

use Time::Local;

my $nargs = @ARGV;

if ($nargs < 1)  {
   print "usage: $0: \"date (YYYYMMDD)\" \"optional: cut off time in hours\" \n";
   exit 1;
}

# Define variables

my $CutOffTime=$ARGV[1] || "";
my $day_start_epoch=0;
my $delay_0_to_thres=0;
my $delay_less_0=0;
my $delay_over_thres=0;
my $delay_thres=0;
my $modelrun="";
my $percent=0;
my $report_excel_string="";
my $report_time_sec=0;
my $total=0;
my $total_products=0;
my $YearMonthDay=$ARGV[0];

my $hiresw_target_file="/nw$ENV{envir}/fix/dashboard_ntcfile_hiresw.targets";
my $ntc_log="$ENV{DATA}/NTC.$YearMonthDay";
my $output_directory="/com/output/prod/$YearMonthDay";
my $target_file="/nw$ENV{envir}/fix/dashboard_ntcfile.targets";

my %cyc=();
my %late_products=();
my %missing_products=();
my %model=();
my %model_delay_0_to_thres=();
my %model_delay_less_0=();
my %model_delay_over_thres=();
my %model_total=();
my %model_total_products=();
my %ncep_avg=();
my %ncep_post_sec=();
my %products=();

# Define subroutines

sub add_to_target;
sub PDY2epoch;
sub string2epoch;
sub time2sec;

# If an hour argument was passed in then determine the time in seconds to stop processing files. If an
# hour argument was not passed then use a full day (86400 seconds).

if ($CutOffTime ne "" )
   {
    $CutOffTime=$CutOffTime*3600;
   }
else
   {
    $CutOffTime=86400;
   }

# Determine what HIRESW jobs ran on the CCS by looking for the existence of the job output (log) file.
# If the job output is found add the corresponding target times to the hashes

opendir OUTPUT, "$output_directory" or die "Could not open $output_directory";
my @output_dir = readdir OUTPUT;

closedir OUTPUT;

foreach my $key (@output_dir)
 {
   SWITCH: {
       if ($key =~ /hiresw_arw_ctl_forecast_00/) {add_to_target('t00z.awpreg_eastarw'); last SWITCH; }
       if ($key =~ /hiresw_arw_ctl_forecast_06/) {add_to_target('t06z.awpreg_westarw'); last SWITCH; }
       if ($key =~ /hiresw_arw_ctl_forecast_12/) {add_to_target('t12z.awpreg_eastarw'); last SWITCH; }
       if ($key =~ /hiresw_arw_ctl_forecast_18/) {add_to_target('t18z.awpreg_akarw'); last SWITCH; }
       if ($key =~ /hiresw_nmm_ctl_forecast_00/) {add_to_target('t00z.awpreg_eastnmm'); last SWITCH; }
       if ($key =~ /hiresw_nmm_ctl_forecast_06/) {add_to_target('t06z.awpreg_westnmm'); last SWITCH; }
       if ($key =~ /hiresw_nmm_ctl_forecast_12/) {add_to_target('t12z.awpreg_eastnmm'); last SWITCH; }
       if ($key =~ /hiresw_nmm_ctl_forecast_18/) {add_to_target('t18z.awpreg_aknmm'); last SWITCH; }
       if ($key =~ /hiresw_hiarw_ctl_forecast_00/) {add_to_target('t00z.awpreg_hiarw'); last SWITCH; }
       if ($key =~ /hiresw_hiarw_ctl_forecast_12/) {add_to_target('t12z.awpreg_hiarw'); last SWITCH; }
       if ($key =~ /hiresw_hinmm_ctl_forecast_00/) {add_to_target('t00z.awpreg_hinmm'); last SWITCH; }
       if ($key =~ /hiresw_hinmm_ctl_forecast_12/) {add_to_target('t12z.awpreg_hinmm'); last SWITCH; }
       if ($key =~ /hiresw_prarw_ctl_forecast_06/) {add_to_target('t06z.awpreg_prarw'); last SWITCH; }
       if ($key =~ /hiresw_prarw_ctl_forecast_18/) {add_to_target('t18z.awpreg_prarw'); last SWITCH; }
       if ($key =~ /hiresw_prnmm_ctl_forecast_06/) {add_to_target('t06z.awpreg_prnmm'); last SWITCH; }
       if ($key =~ /hiresw_prnmm_ctl_forecast_18/) {add_to_target('t18z.awpreg_prnmm'); last SWITCH; }
   }
}

# Open target time file and build several hashes

open(TARGET,$target_file);

while(<TARGET>)
   {
    chop;
    (my $ntcfile, my $fmodel, my $fcyc, my $fproducts, my $n_avg, my $t_avg)=split(/\,/,$_);    
    $modelrun="$fmodel$fcyc";
    $model{$ntcfile}=$fmodel;
    $cyc{$ntcfile}=$fcyc;
    $products{$ntcfile}=$fproducts;
    $ncep_avg{$ntcfile}=$n_avg;
    $total_products=$total_products+$fproducts;
    if (!defined($model_total_products{$modelrun})) {$model_total_products{$modelrun}=0;}
    $model_total_products{$modelrun}=$model_total_products{$modelrun}+$fproducts;
   }
close TARGET;


# Open NTC log file and build hashes using the actual times the files were queued

open(NTC,$ntc_log);
while(<NTC>)
   {
    chop;

    # Grab date information from top of NTC status log 

    if($_ =~ /Report Generated at/)
       {
        (my $j1, my $yr, my $month, my $day, my $hr, my $mn, my $sec, my $zone)=split(/.*(\d\d\d\d).(\d\d).(\d\d) (\d\d):(\d\d):(\d\d).*/,$_);
        my $PDY="$yr$month$day";
        $report_excel_string="$month/$day/$yr";
        my $report_timestring="$yr\-$month\-$day\-23\-55\-00";

        $day_start_epoch=PDY2epoch($PDY);
        $report_time_sec=time2sec($report_timestring);
        my $report_time_epoch=string2epoch($report_timestring);
       }

    if($_!~/  NTC   NTC      NTC/){next;}

    (my $j1, my $j2, my $j3, my $j4, my $n_time, my $t_time, my $delay, my $ntcfile)=split(/\s+/,$_);

    # change any file with an eight character date string in its name to 'yyyymmdd'

    $ntcfile=~s/\d\d\d\d\d\d\d\d/yyyymmdd/;

    # Logic test to always take the most recent time, this 
    # takes care of times when files are sent multiple times
    # in a day

    my $epoch_of_file=string2epoch($n_time)-$day_start_epoch;

    if ( !defined $ncep_post_sec{$ntcfile} ) {
       $ncep_post_sec{$ntcfile}=$epoch_of_file;
    }
    elsif ($epoch_of_file > $ncep_post_sec{$ntcfile}) {
       $ncep_post_sec{$ntcfile}=$epoch_of_file;
    }
      
   }
close NTC;


# Determine statistics by comparing target hashes with actual queue time hashes

foreach my $ntcfile (keys %products)
   {
    my $target_mthres=$ncep_avg{$ntcfile}+900;
    my $target=$ncep_avg{$ntcfile};

    $modelrun="$model{$ntcfile}$cyc{$ntcfile}";
    if(($target >= 0 && $target <= $report_time_sec))
       {
        ############################################
        # 5 Minute Threshold (calculate on from 12Z onward)
        ############################################
        if($target_mthres <= $CutOffTime && ($ncep_post_sec{$ntcfile}<0 || $ncep_post_sec{$ntcfile} eq ""))
           {

            # If a file had a target time earlier than $CutOffTime and there is no record of it being queued then it is MISSING

            $delay_over_thres=$products{$ntcfile}+$delay_over_thres;
            $total=$products{$ntcfile}+$total;

            $model_delay_over_thres{$modelrun}=$products{$ntcfile}+$model_delay_over_thres{$modelrun};
            $model_total{$modelrun}=$products{$ntcfile}+$model_total{$modelrun};
            $missing_products{$ntcfile}="MISSING";
           }
        if( $target_mthres <= $CutOffTime && ($target_mthres <= $report_time_sec && $ncep_post_sec{$ntcfile}>0) && ($ncep_post_sec{$ntcfile} ne ""))
           {

            # Initalize the hash elements 

            if (!defined($products{$ntcfile})) {$products{$ntcfile}=0;}
            if (!defined($model_delay_less_0{$modelrun})) {$model_delay_less_0{$modelrun}=0;}
            if (!defined($model_delay_0_to_thres{$modelrun})) {$model_delay_0_to_thres{$modelrun}=0;}
            if (!defined($model_delay_over_thres{$modelrun})) {$model_delay_over_thres{$modelrun}=0;}
            if (!defined($model_total{$modelrun})) {$model_total{$modelrun}=0;}

            my $delay=$ncep_post_sec{$ntcfile}-$ncep_avg{$ntcfile};

            # Depending on the value of delay place the file name in the proper hash

            if($delay<0)
               {
                $delay_less_0=$delay_less_0+$products{$ntcfile};
                $model_delay_less_0{$modelrun}=$model_delay_less_0{$modelrun}+$products{$ntcfile};
               }
            if($delay>=0&&$delay<=$delay_thres*60)
               {

                # Files that are not early but still below the $delay_thres are stored in the late file hash, but will not impact 
                # the on-time number

                $delay_0_to_thres=$delay_0_to_thres+$products{$ntcfile};
                $model_delay_0_to_thres{$modelrun}=$model_delay_0_to_thres{$modelrun}+$products{$ntcfile};
               }
            if($delay>$delay_thres*60)
               {

                # Files over the $delay_thres are considered late and are stored in the late file hash and impact the on-time number

                $delay_over_thres=$delay_over_thres+$products{$ntcfile};
                $model_delay_over_thres{$modelrun}=$model_delay_over_thres{$modelrun}+$products{$ntcfile};
                my $delay_min=$delay/60;
                $late_products{$ntcfile}="$delay_min";
               }
            if($delay<(-1*$delay_thres)*60)
               {

               # If a file is sent before its target time it is considered early. This information is no longer reported on the dashboard.

                my $delay_min=$delay/60;
                #print "<TR><TD>$report_excel_string</TD><TD>$model{$ntcfile}$cyc{$ntcfile}</TD><TD>$products{$ntcfile}</TD><TD>$ntcfile</TD><TD>$delay_min</TD></TR>\n";
               }
            $total=$products{$ntcfile}+$total;
            $model_total{$modelrun}=$products{$ntcfile}+$model_total{$modelrun};
           }
       }
   }

# Build HTML table that is used by Excel

print "<HTML>\n";
print "<TABLE>\n";
print "<TR><TD>Date</TD><TD>Model</TD><TD>Num Products</TD><TD>Filename</TD><TD>Delay Min</TD></TR>\n";

# Missing products are always listed first

foreach my $ntcfile ( keys %missing_products )
  {
  printf "<TR><TD>%s</TD><TD>%s%s</TD><TD>%s</TD><TD>%s</TD><TD>%s</TD></TR>\n",$report_excel_string,$model{$ntcfile},$cyc{$ntcfile},$products{$ntcfile},$ntcfile,$missing_products{$ntcfile};
  }

# List late products with the most delayed listed first

foreach my $ntcfile (sort {$late_products{$b} <=> $late_products{$a} } keys %late_products)
  {
  printf "<TR><TD>%s</TD><TD>%s%s</TD><TD>%s</TD><TD>%s</TD><TD>%.3f</TD></TR>\n",$report_excel_string,$model{$ntcfile},$cyc{$ntcfile},$products{$ntcfile},$ntcfile,$late_products{$ntcfile};
  }

print "</TABLE>\n";

# Determine on-time percentage

if($total>0)
   {
    $percent=($delay_less_0+$delay_0_to_thres)/$total*100;
    my $total_left=$total_products-$total;
   }
else
   {
    $percent=100;
   }

print "<TABLE>\n";
printf "<TR><TD>Date</TD><TD>Model</TD><TD>Percent > 0 Minutes</TD></TR>\n";
printf "<TR><TD>%s</TD><TD>TOTAL</TD><TD>%3.4f</TD></TR>\n",$report_excel_string,$percent;

foreach $modelrun (sort keys %model_total)
   {
    $percent=($model_delay_less_0{$modelrun}+$model_delay_0_to_thres{$modelrun})/$model_total{$modelrun}*100;
    my $total_left=$model_total_products{$modelrun}-$model_total{$modelrun};
    printf "<TR><TD>%s</TD><TD>%s</TD><TD>%3.4f</TD></TR>\n",$report_excel_string,$modelrun,$percent;
   }
print "</TABLE>\n";
print "</HTML>\n";

sub PDY2epoch ($) {

  # Accept the PDY date and return the equivalent epoch value

   my $PDY = shift;

   my $sec=0;
   my $min=0;
   my $hour=0;
   (my $j, my $year, my $mon, my $day)=split(/(\d\d\d\d)(\d\d)(\d\d)/,$PDY);
   $mon=$mon-1;
   my $timestring=timegm($sec,$min,$hour,$day,$mon,$year);
   return $timestring;
}

sub string2epoch ($) {

  # Accept NTC date string and return the equivalent epoch value

   my $string = shift;

   (my $j, my $year, my $mon, my $day, my $hour, my $min, my $sec)=split(/(\d\d\d\d)-(\d\d)-(\d\d)-(\d\d)-(\d\d)-(\d\d)/,$string);
   $mon=$mon-1;
   my $timestring=timegm($sec,$min,$hour,$day,$mon,$year);
   return $timestring;
}

sub time2sec ($) {

   # Accept the NTC date string and return the equivalent value in seconds

   my $timestring = shift;

   (my $j, my $year, my $mon, my $day, my $hour, my $min, my $sec)=split(/(\d\d\d\d)-(\d\d)-(\d\d)-(\d\d)-(\d\d)-(\d\d)/,$timestring);
   my $seconds=$hour*3600+$min*60+$sec;
   return $seconds;
}

sub add_to_target ($) {

   # Add the baseline values for any hiresw jobs that ran to the appropriate hashes.

   my $NCEPName = shift;
   open(HIRESWTARGET,$hiresw_target_file);

   while(<HIRESWTARGET>)
   {
    chop;
    (my $ntcfile, my $fmodel, my $fcyc, my $fproducts, my $n_avg, my $t_avg)=split(/\,/,$_);
    if ($ntcfile =~ $NCEPName){
      $modelrun="$fmodel$fcyc";
      $model{$ntcfile}=$fmodel;
      $cyc{$ntcfile}=$fcyc;
      $products{$ntcfile}=$fproducts;
      $ncep_avg{$ntcfile}=$n_avg;
      $total_products=$total_products+$fproducts;
      if (!defined($model_total_products{$modelrun})) {$model_total_products{$modelrun}=0;}
      $model_total_products{$modelrun}=$model_total_products{$modelrun}+$fproducts;
    }
   }
 close HIRESWTARGET;
}

