#! /cdf/scratch/cdfopr/cdfcalib/products/bin/perl

#############
#
#  ValidSubmitter.pl
#
#    Submits validation jobs for runs which
#      - have pass 17test1 defined
#      - have validation files available [ see "CalibValidFiles.pl" ]
#      - have not had validations submitted already
#


use strict;
use lib '../CommonLibs/';
require "db_queries.pl";
require "CalibValidFiles.pl";
require "CalibStatus.pl";

#$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;

# comment to DB
printf("Connecting to dB....\n\n\n");
my $dbh = DBI->connect('dbi:Oracle:cdfonprd','cdf_reader','reader') 
    or die "Error connecting $DBI::errstr\n";

# arbitrary
my $firstrun = $ARGV[1];
my $lastrun = $ARGV[2];

# some definitions -> put these in a common header later
#my $status_dir = "/cdf/www/offline/calibrations/Status";
my $status_dir = "/cdf/prdwww/cdfprd_cal/Status";
#my $status_html = "http://www-cdf.fnal.gov/offline/calibrations/Status";
my $status_html = "http://www-cdf.fnal.gov/prdwww/cdfprd_cal/Status";

#my $val_output_dir = "/export/data2/cdfopr/validation/";
#my $val_output_dir = "/cdf/home/cdfprd_cal/data2/validation_6.1.1c/";
my $val_output_dir = "/cdf/home/cdfprd_cal/data2/validation/";
#my $val_output_dir = "/cdf/proj/102.calib/validation/";
#my $submit_dir = "/cdf/scratch/cdfopr/danielw/Validation/Submit/";
#my $submit_dir = "/cdf/home/cdfprd_cal/scratch/CalibrationFramework/cdfopr/calib/Validation/Submit";
my $submit_dir = "./Submit";
my @strips = ("$ARGV[0]");

my @strips_todo;
#wen","wmn","zee");

# associate process with user
my %emails;
$emails{"mb"} = $emails{"wen"} = $emails{"wmn"} = $emails{"zee"} = $emails{"zmm"} = $emails{"jpsi"}  = $emails{"zee_frontier_test"} = "elee\@FNAL.GOV";

printf("Getting unvalidated runs...\n\n\n\n");
my %runsv = &get_unvalidated_runs($dbh,$firstrun,$lastrun);

#my @kr;
#@kr = keys %runsv;

#printf("Found runs @kr\n");
my $k;

my $stage = "Valid";

# get list of ready rungroups [ not yet submitted ]
printf("Getting rungroups...\n");
my @rungroups = &getReadyRungroups();

printf("Getting validation files...\n");
my %vfiles_strip_run = &getAllCalibValidFiles();

my %vfiles;

# this should loop over rungroups, and check whether the rungroup has been submitted and pass 17test1 exists

my $rg;
foreach $rg (@rungroups)
{
    printf("Run $rg need validating. Checking run status...\n");
    my @runs = &getRuns($rg);
    my $rs = 1;

 
    # check to make sure all are pass17test1 and not pass17
    my $run;
    foreach $run (@runs)
     {	
	 printf("[run $run $runsv{$run} -> $rs] ");
       $rs = $rs && ($runsv{$run});
     }
    printf("[ status = $rs ]\n");

    if ($rs)
    {

	# see if there are strips in this RG that have not been submited
	my @stripsdone = &checkSubmittedRungroup($rg);
	my $nstripsdone = @stripsdone+1-1;
	
	printf("Submission already done for $nstripsdone strips: @stripsdone");
	
	my $ntodo=0;
	my $strip;
	foreach $strip (@strips)
	{
	    my $sdone = 0;
	    my $i=0;
	    for ($i=0;$i<$nstripsdone;$i++)
	    {
		if ($stripsdone[$i] eq $strip)
		{
		    $sdone = 1;
		}
		printf("strip $strip =?= $stripsdone[$i] done=$sdone\n");
	    }
	    if (!$sdone)
	    {
		$strips_todo[$ntodo++] = $strip;
	    }
	}
	printf("Submission still needed for  \"@strips_todo\" strips in runs: @runs\n");

	foreach $run (@runs)
	{
	    printf("[ looking for files for $run ]\n");
	    my $strip;
	    my %vfiles_run;
	    my $validavail = 1;
	    my $missing ="";
	    
	    foreach $strip (@strips_todo)
	    {
		
		# look for calib files
		my $tag = $strip.".".$run;
		my $v_s_r = $vfiles_strip_run{$tag};
		my @vfiles_run_strip;
		if ($v_s_r ne "")
		{
		    @vfiles_run_strip = @$v_s_r;
		
		    printf(" Files available for $strip in run $run:".(scalar @vfiles_run_strip)."\n");
		    $vfiles_run{$strip} = [ @vfiles_run_strip ];
		}
		else
		{
		    printf(" NO Files available for $strip in run $run\n");
		    $validavail = 0;
		    $missing = $missing." ".$strip;
		}
	    }
	
	    if ($validavail)
	    {
		foreach $strip (@strips_todo)
		{
		    my $vnew = $vfiles_run{$strip};
		    my @vnewa = @$vnew;
		    my $vold = $vfiles{$strip};
		    if ($vold eq "")
		    {
			$vfiles{$strip} = [ @vnewa ];
		    }
		    else
		    {
			my @volda = @$vold;
			$vfiles{$strip} = [ (@volda,@vnewa) ];
#		    printf(" New files are : @vnewa\nOld files are: @volda\n\n");
			
		    }
		}
		printf(" All files available for validation!\n");
	    }
	    else
	    {
		printf("Missing files for $missing\n");
	    }
	    
	}
    


	if ((scalar @runs) > 0)
	{
	    doValid(@runs);
	    
	}
    }
}


exit(0);

sub doValid()
{
    my @rlist = @_;
    printf("submitting validaton for [ @rlist ]\n");
    my $strip;

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

    my $cdir = "${status_dir}/${stage}_Submitted/${minrun}_${maxrun}";
    printf("Making $cdir\n");
    `mkdir $cdir`;


    foreach $strip (@strips_todo)
    {
#	if (1==2)
	{
	    
	    my $vfiles_strip = $vfiles{$strip};
	    my @vfiles_strip_arr = @$vfiles_strip;
	    printf("Strips ${strip}:".@vfiles_strip_arr." files available\n");
	    my $pdir = $cdir."/$strip";
	    `mkdir $pdir`;
	    
	    printf("Writing to $pdir/runs.list\n");
	    open(ROUT,">$pdir/runs.list");
	    my $run;
	    foreach $run (@rlist)
	    {
		print ROUT "$run\n";
	    }
	    close(ROUT);
	    
	    printf("Writing file list to ${pdir}/files.list\n");
	    
	    open(FLOUT,">${pdir}/files.list");
	    my $cf;
	    foreach $cf ( @vfiles_strip_arr)
	    {
		print FLOUT "$cf\n";
	    }
	    close(FLOUT);
	    
	    # submission script is in charge of making the output
	    my $cmd = "cp ${pdir}/{runs,files}.list ${submit_dir}/${strip}; cd ${submit_dir}/${strip}; ./submit.sh ./files.list ${val_output_dir} ${minrun}_${maxrun} ${strip}";
	    printf("Running: $cmd\n");
	    my @cmdres = `$cmd | grep "ResultsFile" | awk '{print \$2}'`;
	    printf("Result: @cmdres\n");
	    my $rf;
	    foreach $rf (@cmdres)
	    {
		chop($rf);
		if ($rf ne "")
		{
		    my $cmd2 = "mv ${submit_dir}/${strip}/$rf ${pdir}";
		    printf("Moving result file $cmd2\n");
		    `$cmd2`;
		}
	    }
	    
	    # indicate the status
	    open(SOUT,">${pdir}/status.txt");
	    print SOUT "Submitted";
	    close (SOUT);
	    
	    # send an email
	    my $hdir = "${status_html}/${stage}_Submitted/${minrun}_${maxrun}/$strip";
	    my $message = "Submission of validation samples for strip $strip in runs ${minrun}_${maxrun}:\n$hdir\n";
	    
	    my $recip = $emails{$strip};
	    open(MOUT,">.mail.${strip}.$$");
	    print MOUT $message;
	    close(MOUT);
	    my $res = `mail -s \"Submitted validation sample for $strip in runs ($minrun-$maxrun)" $recip < .mail.${strip}.$$`;
	    `rm .mail.${strip}.$$`;
	    printf("Sent \"$message\" to $recip with result $res\n");
	}
#	else
	#{
	  #  printf("Strip $strip already submitted for runs ($minrun-$maxrun)\n");
#	}
    }

}

sub requestApproval()
{
    my @rlist = @_;
    printf("requesting approval  for for [ @rlist ]\n");
    my $strip;

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

    my $cdir = "${status_html}/${stage}_Pending/${minrun}_${maxrun}";
    my $cdirl = "${status_dir}/${stage}_Pending/${minrun}_${maxrun}";
    
    printf("Writing to $cdirl/runs.list\n");
    open(ROUT,">$cdirl/runs.list");
    my $run;
    foreach $run (@rlist)
    {
	print ROUT "$run\n";
    }
    close(ROUT);

    foreach $strip (@strips_todo)
    {
        my $pdir = $cdir."/$strip";
	my $message = "Please review the new calibrations for $strip covering runs ($minrun-$maxrun):\n$pdir/index.html\n";
	
    }
}

# same as ValidRequester.pl
sub get_unvalidated_runs
{
# 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) = @_;
    my %unvruns;

  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 rc.runnumber in (select lorun from passcalibs where pass_index =
  ( select pass_index from passes where passname like '10A' and retired is null) )
    and pt.runnumber = rc.runnumber
    and rs.runnumber = rc.runnumber
    and rc.runnumber >= ?
    and rc.runnumber <= ?
  order by rc.runnumber";


#    and rc.runnumber not in (select lorun from passcalibs where pass_index =
#  ( select pass_index from passes where passname like '17' and retired is null) )

    my $sth = $dbh->prepare($sql);
    $sth->execute($start_run,$end_run);
#    printf("Pushing runs...$start_run $end_run\n");
    while (my $row = $sth->fetchrow) { $unvruns{$row} = 1; }
#    printf("Pushed runs...$start_run $end_run\n");
    return %unvruns;
}
