#! /usr/bin/env perl
#
#  SegDBM parameters
#
#    RunID     Current Run ID
#    FillDelay Time between end of last run hour and start of fill
#
$|=1;  #autoflush!!
$SIG{CHLD} = 'IGNORE';

$RunID=`cat $ENV{DMTPARS}/RunID`;
chomp $RunID;
$FillDelay=300;
$Debug = grep(/--debug/, @ARGV);
#
#  Define Subroutines.
sub fillSeg;
sub submit_job;
sub tStamp;

#--------------------------------------  Set loop parameters
$timeStep=128;
$loopGPS=0;
$loopEnd=0;
$Online=1;
if (defined($loopDir=$ENV{SEGLOOPDIR})) {
    $loopGPS="$ENV{SEGLOOPTIME}";
    $loopEnd="$ENV{SEGLOOPEND}";
    $Online =0;
}
print("SegDirectory online mode=$Online\n") if($Debug);
print("Loop parameters: Dir=$loopDir, start=$loopGPS, end=$loopEnd\n") if ($Debug && ! $Online);
if (!defined($IfoList="$ENV{DMTIFOS}") ) {
    print "DMTIFOS environment variable is not defined.\n";
    exit 1;
} elsif ($Debug) {
    print "IFO list: $IfoList\n";
}

#--------------------------------------  Loop over data
while ($Online || $loopGPS < $loopEnd) {

#--------------------------------------  Loop over IFOs
    foreach my $IFO (split(' ', $IfoList)) {
        next if (substr($IFO,1,1) eq "0");
        $DBdir="$ENV{GDSAPACHE}/SegList/$RunID/$IFO";
        if (! $Online) {
	    my $pfx=substr($IFO,0,1);
	    my $GPS4=substr($loopGPS,0,4);
	    my $file="$loopDir/${pfx}-R-${GPS4}/${pfx}-R-${loopGPS}-16.gwf";
            next if (! -f $file);
	    print "getting data from $file\n" if ($Debug);
	    @List=`SegData -ifo $IFO -infile $file`;
	} else {
            @List=`SegEpics $IFO`;
	}
        $SegNo=0;
        $StartGPS=0;
        $EndGPS=0;
        for (my $i=0 ; $i<@List ; $i++) {
            my $line=$List[$i];
            chomp $line;
            if ($line =~ s/^Segment Number:\s*//) {
	        $SegNo=$line;
            } elsif ($line =~ s/^Start Time:\s*//) {
	        $StartGPS=$line;
            } elsif ($line =~ s/^Stop Time:\s*//) {
	        $EndGPS=$line;
            }
        }
        print "Segment parameters: SegNo=$SegNo, start=$StartGPS, end=$EndGPS\n" if($Debug);

#---------------------------------------  Set up Segment directory 
        $SegID=sprintf("%s-%04d", $IFO, $SegNo);
        print "Segment: $SegID, Start Time: $StartGPS, End Time: $EndGPS\n";
        if ($SegNo !=0 && $StartGPS != 0) {
            my $SegDir="$DBdir/$SegID";
            if (! -d $SegDir ) {
                if (mkdir($SegDir, 0775)) {
                    print "Created directory: $SegDir\n";
                    open(STARTFILE, ">$SegDir/StartTime");
                    print(STARTFILE "$StartGPS" );
                    close(STARTFILE);
                } else {
                    print "Unable to create $SegDir: $!\n";
                }
            }
            if ($EndGPS != 0 && -d $SegDir && ! -f "$SegDir/EndTime" ) {
                open(ENDFILE, ">$SegDir/EndTime");
                print(ENDFILE "$EndGPS" );
                close(ENDFILE);
            }
        }

#---------------------------------------  Look for Segments that need info
        opendir(DIRHANDLE, $DBdir);
        while (defined($SegID = readdir(DIRHANDLE))) {
	    my $SegDir="$DBdir/$SegID";
	    next if ( -l "$SegDir/fillStat" || ! -f "$SegDir/EndTime" );
	    my $now=`when 0 %s`;
	    chomp $now;
	    my $endt=`cat $SegDir/EndTime`;
	    chomp $endt;
	    my $htest = ($endt + 3599) / 3600;
	    my $hnow  = ($now - $FillDelay) / 3600;
	    next if ($hnow < $htest);
	    symlink("filling", "$SegDir/fillStat");
	    fillSeg($SegDir);
        }
    }

#---------------------------------------  Get/wait for next Time
    if ($Online) {
        sleep($timeStep);
    } else {
        $loopGPS += $timeStep;
    }
}

#=======================================  Populate the segment table with ???
sub fillSeg {
    my $SegDir=$_[0];
    my @NmList=split('/', $SegDir);
    my $nlv   = @NmList;
    my $Ifo   = $NmList[$nlv-2];
    my $SegID = $NmList[$nlv-1];
    my $tStart = `cat $SegDir/StartTime`;
    chomp $tStart;
    my $tEnd   = `cat $SegDir/EndTime`;
    chomp $tEnd;

    #-----------------------------------  Make the new files.
    print "Populating segment $SegID for IFO $Ifo in $SegDir\n";
    my $cfgdir = "$ENV{DMTHOME}/$ENV{DMTVERSION}/etc/SegDirectory";
    @MonList   = `ls -1 $cfgdir/$Ifo-*.cfg`;
    foreach my $cfile (@MonList) {
	my $cfg  = $cfile;
	chomp $cfg;
	my $Mon  = "$cfg";
	$Mon =~ s|^(.*/)*${Ifo}-||;
	$Mon =~ s/\.cfg$//;
	my $tdir = "$ENV{DMTRENDIR}/$Mon";
	$tdir = "${tdir}_$Ifo" if (! (-d $tdir));
	if (! (-d $tdir)) {
	    print "Can't find trend directory for Monitor $Mon\n";
	    next;
	}
	my $outf = "$SegDir/$Mon\.txt";
	my $cmd  = "TrendAvg -start $tStart -end $tEnd -conf $cfg -td $tdir -out $outf";
	my $cwd  = "$cfgdir";
	submit_job($cmd, $cwd);
    }

    #-----------------------------------  Mark the directory as finished
    unlink("$SegDir/fillStat") if (-l "$SegDir/fillStat");
    symlink("complete", "$SegDir/fillStat");
}

#=======================================  Submit a job
sub submit_job {
    #----------------------------------- get the command
    my $Cmd  = $_[0];
    my $Cwd  = $_[1];
    my $Time = tStamp();

    #-----------------------------------  Run the new process.
    print "Starting command: $Cmd (CWD: $Cwd)\n" if ($Debug);
    my $child = fork();
    if (!defined($child)) {
	print "$Time [$Pnam] Fork failed!\n";
    } elsif (!$child) {
	chdir($Cwd);
	# setpgrp();
	$ENV{PWD} = $Cwd;
	exec($Cmd) or print "$Time [SegDirectory] Failed to exec $Cmd\n";
	exit();
    } else {
	print "$Time [SegDirectory] Process $child created \n";
    }
}

#=======================================  Generate a time stamp
sub tStamp {
    (my $sec, my $min, my $hour, my $mday, my $mon, my $year) = localtime();
    $year += 1900;
    $mon  += 1;
    return sprintf("%d.\%02d.\%02d-\%02d.\%02d.\%02d",
                   $year, $mon, $mday,$hour, $min, $sec);
}
