#!/usr/bin/perl

use strict;
use lib '/cdf/scratch/cdfopr/danielw/CommonLibs';

require "db_queries.pl";
require "CalibValidFiles.pl";
require "CalibStatus.pl";
#require "CommonDefs.pl";

my $status_dir = "/cdf/www/offline/calibrations/Status";
my $status_html = "http://www-cdf.fnal.gov/offline/calibrations/Status";

my %streams;
$streams{"pes-align"} = "b";
$streams{"pes-gain"} = "g";
$streams{"emtiming"} = "b";
$streams{"hadtiming"} = "g";
$streams{"cal-had"} = "j";
$streams{"miniplug"} = "g";
$streams{"cal-em"} = "b";
$streams{"tof"} = "g";

my %names;
$names{"pes-align"} = "PES";
$names{"pes-gain"} = "PES";
$names{"emtiming"} = "EMT";
$names{"hadtiming"} = "HT";
$names{"cal-had"} = "CHA";
$names{"miniplug"} = "MP";
$names{"cal-em"} = "CEM";
$names{"tof"} = "TOF";

my @jobnames = ("gphysr","jphysr","bphysr");

#$ENV{'ORACLE_HOME'} = '/home/cdfsoft/products/oracle_client/v9_2_0_1a/Linux+2';
$ENV{'ORACLE_HOME'} = $ENV{'CDFSOFT2_DIR'}.'/../../../products/oracle_client/v9_2_0_1a/Linux+2';
#$ENV{'TNS_ADMIN'} = '/home/cdfsoft/dist/oracle_tnsnames';
$ENV{'TNS_ADMIN'} = $ENV{'CDFSOFT2_DIR'}.'/../../oracle_tnsnames';

use DBI;

my $dbh = DBI->connect('dbi:Oracle:cdfonprd','cdf_reader','reader') 
	or die "Error connecting $DBI::errstr\n";

my $svx_txt = '';
my $cot_txt = '';
my $beamlines_txt = '';
my $calib_txt = '';

my $donecolor="green";
my $missingcolor="red";
my $notyetcolor="blue";

#my $firstrun = 228596;
my $firstrun = 256840;
my $lastrun  = 999999;

#printf("Looking for files");
printf("<!-- Querying file listsings for output -->\n");
my %cfiles_proc_run = &getNumCalibValidFiles();

my @keysc = keys %cfiles_proc_run;

#    printf("<!-- All valid keys are: @keysc -->\n");
#



my @runsv;
printf("<!-- Querying db for goodruns -->\n");
&get_good_runs($dbh,$firstrun,$lastrun,\@runsv);
my @runs = reverse @runsv;

my $maxrun=$runs[0];
my $minrun=$runs[ (scalar @runs)-1 ];

#printf("<!-- good runs: @runs -->\n");

printf("<!-- Querying SAM from runs $minrun $maxrun -->\n");
my %cfilesmax_stream_run = &getAllMaxCalibFiles($minrun,$maxrun);

my %current_jobs = &getAllSamgliaJID();

#    printf("<!-- All valid keys are: @keysc -->\n");


my $run;
my @rstatus;
my @link;
my $datestring = `date`;
chop($datestring);


my $dfree = &getSpaceLeft();
  
printf("<center>Updated: <font color=green>$datestring</font> | Earliest run considered: <font color=green>$firstrun</font>| Disk usage = <font color=green>$dfree</font><br>\n Color Key: <font color=$missingcolor>missing, prereqs available</font> | <font color=$notyetcolor>missing, waiting on prereq </font> |  <font color=$donecolor>done</font><br><br><br>\n");


#printf("Disk usage = $dfree<br>\n");

printf("<table cellSpacing=0 cellPadding=4 border=1>");
printf("<tr><th> Run Number</th><th> Age [hrs]</th><th> SVX, COT<br>calibrated</th><th>pass 10A<br>built</th><th>SVX,COT<br>Beamlines</th><th>pass 17A<br>built</th><th>Subdetector Calibration</th><th>pass 17test1<br>built</th><th>Validation</th><th>pass 17<br>built</th>\n");
foreach $run (@runs)
{
    $datestring= `date`;
    chop($datestring);
    printf("<!-- [ $datestring ] Starting run $run --!>\n");
    my $i=0;
    $link[$i] = "";

    printf("<!-- [ $datestring ] checking db status $run --!>\n");
    my $svxstatus = &check_process( $dbh, $run, "PROD_PHYSICS_SVX");
    
    
    my $cotlink = "http://www-cdfonline.fnal.gov/cgi/internal/mon/cdfdoc/ConsumerGifs/makeConsumerGifs.pl?choice=Stage0&run=$run";

    my $cotstatus = &check_process( $dbh, $run, "PROD_PHYSICS_COT");

    
    my $pass10A = &check_pass( $dbh, $run, "10A");
    
    my	$beamscot = &check_process( $dbh, $run, "PAD_PHYSICS_COTBEAM");
    my	$beamssvx = &check_process( $dbh, $run, "PAD_PHYSICS_SVXBEAM");
    
    my $pass17test1 = &check_pass( $dbh, $run, "17TEST1");
    my $pass17 = &check_pass( $dbh, $run, "17");
    my $pass17A = &check_pass( $dbh, $run, "17A");

    my $age = &get_run_age( $dbh, $run);

    my $proc;
    my @proccfiles;
    my @maxcfiles;
    my @procpending;
    my @stripvfiles;
    my @strippending;
    my @stripres;
    my @stripnfiles;
    my @ntuplepending;
    my @ntupleres;
    my @usedsetvalid;
    my $i=0;
    my $rungroup = &getRunGroup($run);
    my @processes = ("pes-align","emtiming","cal-em","cal-had","pes-gain","hadtiming","miniplug","tof");
    my @strips = ("zee","wen","zmm","wmn","jpsi","mb");
    my %usedsets;
    my @usedsetvalid;
    $usedsets{"pes-align"} = "L3_PHYSICS_SMX";

    my $allusedsetsvalid = 1;

    printf("<!-- [ $datestring ] checking checking files --!>\n");
    foreach $proc (@processes)
    {

	my $tag = $proc.".".$run;
	printf("<!-- [ $datestring ] checking checking files $proc tag is $tag  in stream $streams{$proc}--!>\n");

	$maxcfiles[$i] = $cfilesmax_stream_run{$streams{$proc}.".".$run};

	# +1 -1 to convert "" to 0
	$proccfiles[$i] = $cfiles_proc_run{$tag} +1 -1;

	
	if (!$rungroup ==0)
	{
	    my $procres = &getStatusRungroupProc("Calib","Pending",$rungroup,$proc);
	    $procpending[$i] = "";

	    if ($procres =~ /Error/)
	    {
		$procpending[$i] = "Error";
	    }
	    if ($procres =~ /Ready/)
	    {
		$procpending[$i] = "$status_html/Calib_Pending/$rungroup/$proc/";
		if ($usedsets{$proc} ne "")
		{ $usedsetvalid[$i] = &check_process( $dbh, $run, $usedsets{$proc} );}
	    }

	}
	$allusedsetsvalid = $allusedsetsvalid && $usedsetvalid[$i];
	$i++;
    }

    my $strip;
    $i=0;
    foreach $strip (@strips)
    {
	printf("<!-- [ $datestring ] checking checking files $strip --!>\n");

	my $tag = $strip.".".$run;

	# +1 -1 to convert "" to 0
	$stripvfiles[$i] = $cfiles_proc_run{$tag} +1 -1;

#	printf("<!-- files for >${strip}< >${run}<: $stripvfiles[$i] -->");
	if (!$rungroup ==0)
	{
	    $stripres[$i] = &getStatusRungroupProc("Valid","Submitted",$rungroup,$strip);
	    $strippending[$i] = "$status_html/Valid_Submitted/$rungroup/$strip/";
	}

	my @nfiles;
# = &getValidNtuples($strip,$rungroup);
	$stripnfiles[$i] = scalar @nfiles;
#	printf("<!-- files for >${strip}< >${run}<: $stripvfiles[$i] -->");
	if (!$rungroup ==0)
	{
	    $ntupleres[$i] = &getStatusRungroupProc("Valid","Plots",$rungroup,$strip);
	    $ntuplepending[$i] = "$status_html/Valid_Plots/$rungroup/$strip/";
	}

	$i++;
    }


    ##########################
    ## produce the table

    
	printf("<!-- [ $datestring ] making table --!>\n");

    printf("<tr>");
    printf("<td><a href=\"http://www-cdfonline.fnal.gov/java/cdfdb/servlet/RunSummary?RUN_NUMBER=$run\"><font color=black>$run</font></a></td><td>$age</td>");

    my $color = $donecolor;
    if ($svxstatus==0) { $color = $missingcolor; }
    printf("<td><font color=$color>$svxstatus</font>,");

    $color = $donecolor;
    if ($cotstatus==0) { $color = $missingcolor; }
    printf("<font color=$color>$cotstatus</font> [<a href=\"$cotlink\"><font size=1 color=$donecolor>plots</font></a>]</td>");

    $color = $donecolor;
    if ($pass10A==0) 
    {

    }
    printf("<td><font color=$color>$pass10A</font></td>");

    $color = $donecolor;
    if ($beamssvx==0) { 	
	if ($cotstatus && $svxstatus)
	{ $color = $missingcolor; }
	else
	{ $color = $notyetcolor; } 
    }			    

    printf("<td><font color=$color>$beamssvx</font>,");
    $color = $donecolor;
    if ($beamscot==0) 
    {
 	if ($cotstatus && $svxstatus)
	{ $color = $missingcolor; }
	else
	{ $color = $notyetcolor; }
    }
    
    printf("<font color=$color>$beamscot</font></td>");

    $color = $donecolor;
    if ($pass17A==0) 
    {
	if ($beamssvx && $beamscot)
	{ $color = $missingcolor; }
	else
	{ $color = $notyetcolor; }
    }
    printf("<td><font color=$color>$pass17A</font></td>");


    printf("<td>");
    my $i=0;
    my $nonemissing=1;

    my $jn;
    foreach $jn (@jobnames)
    {
      my $tag = $jn.".".$run;
      if ($current_jobs{$tag} ne "")
	{ 
	 printf("<a href=\"$current_jobs{$tag}\">CalibExe running $jn</a>\n<br>");
	}
    }


    printf("<table border=0>");
    printf("<tr>");
    foreach $proc (@processes)
    {
	printf("<td>$names{$proc}</td>");
    }
    printf("<tr>");

    foreach $proc (@processes)
    {

	$color = $donecolor;
	if ($proccfiles[$i]<$maxcfiles[$i])
	{
	    # if 10A isn't ready, or pass17 already built, there's no problem
	    if ($pass10A||$pass17)
	    { $color = $missingcolor;$nonemissing=0 }
	    else
	    { $color = $notyetcolor; }
	}
	
	printf("<td><font color=$color>$proccfiles[$i]</font>/$maxcfiles[$i]</td>");

	$i++;
	    
    }
    printf("</table></td>");

    # pass17test1 depends on all used sets being available

    $color = $donecolor;
    if ($pass17test1==0) 
    {
	if ($allusedsetsvalid)
	{ $color = $missingcolor;}
	else
	{ $color = $notyetcolor; }
    }

    printf("<td><font color=$color>$pass17test1</font></td>");
    $nonemissing=1;

    # need to check for validation files and validation ready
    # not doing that yet, so just saying "No files"
    my $badcolorfiles=$missingcolor;
    if ($pass10A==0)
    {
	$badcolorfiles=$notyetcolor;
    }

     printf("<td>");
    my $i=0;
    my $nonemissing=1;
    printf("<table border=0>");
    printf("<tr>");
    foreach $strip (@strips)
    {
	printf("<td>$strip</td>");
    }
    printf("</tr>");

    printf("<tr>");
    foreach $strip (@strips)
    {
#	printf("<!-- strip $strip i=$i files = $stripvfiles[$i] pending= $strippending[$i] res = $stripres[$i]-->\n");

	$color = $donecolor;
	my $badcolor=$notyetcolor;

	if ($pass10A)
	{
	    $badcolor = $missingcolor;
	}

	# strip name and number of stripped files
	if ($stripvfiles[$i] ne 0)
	{
	    printf("<td><font color=$donecolor>$stripvfiles[$i]</font></td>");
	}
	else
	{
	    printf("<td><font color=$badcolor>$stripvfiles[$i]</font></td>");
	    # nothing else can be ready now
	    $badcolor=$notyetcolor;
	}
	printf("</td>");

	$i++;
	    
    }
    printf("</tr>");
    printf("</table></td>");

    $nonemissing=0;

    # need variable which tells us if all have been validated. for now just look at valid samples
    $color = $donecolor;
    if ($pass17==0) 
    { 
	if ($nonemissing)
	{ $color = $missingcolor;}
	else
	{ $color = $notyetcolor; }
    }
    printf("<td><font color=$color>$pass17</font></td>");    

    printf("</tr>\n");

}
    printf("</table></center>");

$dbh->disconnect;

exit;

sub check_pass
{
    #i) db handle ii) run iii) pass name vi) jobset name v) time offset in hours 
    
    # this checks that a run is not in a pass AND (if specified) is missing a jobset
    # returns a string if missing
    
    my ( $dbh, $run, $pass ) = @_;

    my $pass_index = &get_pass_index( $dbh, $pass );

    my $sth = $dbh->prepare( "select lorun from passcalibs 
                          where lorun = ? and pass_index = ?" );

    $sth->execute( $run, $pass_index );
    if ( $sth->fetchrow ) { return 1 };
    return 0;
}

sub check_process
{
    
    my ( $dbh, $run, $process_name ) = @_;
    
    
    my $latest = &get_latest_version( $dbh, $run, $process_name );

    return $latest;
}

sub get_good_runs
{
# returns an array of good runs (farms definiton minus csl_summary) 

# Arguments: 1) database handle 2) start run 3 array to return runs 
# fills hash with key = run and value = run terminate time 

  my ( $dbh, $start_run, $end_run,$run) = @_;

  my $sql = 
  "select rc.runnumber
  from runconfigurations rc, run_status rs, physicstables pt
  where rs.runcontrol_status != 0 
    and rs.shiftcrew_status != 0
    and rc.b0integratedlivelumi > 10.0
    and rc.csl_neventsoutput > 1000
    and not pt.physicstablename like '%TEST%'
    and (pt.physicstablename like '%Phyiscs' or pt.physicstablename like '%PHYSICS%')
    and pt.runnumber = rc.runnumber
    and rs.runnumber = rc.runnumber
    and rc.runnumber >= ?
    and rc.runnumber <= ?
  order by rc.runnumber"; 

  my $sth = $dbh->prepare($sql);
  $sth->execute($start_run,$end_run);
  
#  printf("request = $sql\n");
  
  while (my $row = $sth->fetchrow) { push @$run, $row }

  return 1;
}
