#! /usr/bin/env perl

use warnings;
use strict;
use POSIX ":sys_wait_h";
use Sys::Hostname;

my $clients = 2;
my $start_time = 8;
my $end_time = 18; # +1, as it goes until the hour changes.

my $t0 = time();
my $time = 0;
my $dt = 0;
my $hostname = hostname();

for (my $v = 0; $v <= 2; $v++) {
    system("ls /data/${hostname}.${v}");
}

my @tops = </data/${hostname}*>;

my @Tpid = ();
my @volume = ();

for (my $i = 0; $i <= $#tops; $i++) {
    $Tpid[$i] = -1;
    $volume[$i] = '';
}

while ($#tops > -1) {
    for (my $i = 0; $i <= $#volume; $i++) {
	if ($Tpid[$i] == -1) { next; } # hasn't started yet
	my $child = waitpid($Tpid[$i],WNOHANG);
	if ($child != 0) {
	    $time = time;
	    $dt = $time - $t0;
	    print "$dt $i $Tpid[$i] $volume[$i] FINISH $child\n";
	    $volume[$i] = '';
	} # End print client report.
    } # End scan over clients for reaping.

    for (my $i = 0; $i <= $#volume; $i++) {
	if ($volume[$i] ne '') { next; }
	if ($#tops != -1) {
	    $volume[$i] = shift(@tops);
	    $Tpid[$i] = fork();

	    if ($Tpid[$i] == 0) {
		# I am a top level client.
		my @subdirs = <$volume[$i]/nebulous/*>;
		$time = time;
		$dt = $time - $t0;
		print "$dt $i $volume[$i] START\n";
		
		foreach my $sd (@subdirs) {
		    $time = time;
		    $dt = $time - $t0;
		    print "$dt $i $volume[$i] $sd\n";
		    
		    my @subsubdirs = <$sd/*>;
		    my @Cpid = ();
		    my @work = ();
		    for (my $j = 0; $j < $clients; $j++) {
			$work[$j] = '';
			$Cpid[$j] = -1;
		    }
		    
		    while ($#subsubdirs > -1) {
			for (my $j = 0; $j < $clients; $j++) {
			    if ($Cpid[$j] == -1) { next; } # hasn't started yet
			    my $child = waitpid($Cpid[$j],WNOHANG);
			    if ($child != 0) {
				$time = time;
				$dt = $time - $t0;
				print "$dt $i $j $Cpid[$j] $work[$j] FINISH $child\n";
				$work[$j] = '';
			    } # End print client report.
			} # End scan over clients for reaping.
			
			for (my $j = 0; $j < $clients; $j++) {
			    if ($work[$j] ne '') { next; }
			    if ($#subsubdirs != -1) {
				$work[$j] = shift(@subsubdirs);
				$Cpid[$j] = fork();
				
				if ($Cpid[$j] == 0) {
				    # I am a bottom level client
				    $time = time;
				    $dt = $time - $t0;
				    print "$dt $i $j $work[$j]\n";
				    my $exit_code = do_work($work[$j]);
				    exit($exit_code);
				} # End bottom level client loop.
			    } # End adding new jobs
			} # End scan over clients for spawning.
			
			sleep(2); # To relax a bit.
		    } # End scan over subdirectories to check.
		    
		    my $all_children_done = 0;

		    while ($all_children_done != 1) {
			$all_children_done = 1;

			for (my $j = 0; $j < $clients; $j++) {
			    if ($Cpid[$j] == -1) { next; } # hasn't started yet
			    my $child = waitpid($Cpid[$j],WNOHANG);
			    if ($child != 0) {
				$time = time;
				$dt = $time - $t0;
				print "$dt $i $j $Cpid[$j] $work[$j] FINISH $child\n";
				$work[$j] = '';
			    } # End print client report.
			    else {
				$all_children_done = 0;
			    }
			} # End scan over clients for reaping.
			
			sleep(5);
		    }

		} # End scan over top level directories
		exit(0);
	    } # End top level client job
	}
    }    
} 

my $active = 1;
while ($active != 0) {
    $active = 0;
    for (my $i = 0; $i <= $#volume; $i++) {
	if ($Tpid[$i] == -1) { next; } # hasn't started yet
	my $child = waitpid($Tpid[$i],WNOHANG);
	if ($child == -1) { next; } # Nothing here.
	if ($child != 0) {
	    $time = time;
	    $dt = $time - $t0;
	    print "$dt $i $Tpid[$i] $volume[$i] FINISH $child\n";
	    $volume[$i] = '';
	} # End print client report.
	$active = 1;
    } # End scan over clients for reaping.
    sleep(60);
}

    
sub do_work {
    my $directory = shift(@_);
    unless (-d $directory) { return(0); } # Skip not directories
    my $out_log = "${directory}.OTA_md5sums"; 
    if ($out_log =~ /ippb02/) {
	$out_log = "/data/ippb01.0/watersc1/ippb02_md5sums/${directory}.OTA_md5sums";
    }
    my $do_it = 1;
    
    if ($do_it == 1) {
#	if (-e $out_log) { 
#            # Do not overwrite already existing files.
#	    print ">> $directory $out_log Already Exists.\n";
#	    return(0); 
#	} 
	
	my @localtime = localtime();
	while (($localtime[2] < $start_time)||($localtime[2] > $end_time)) {
	    sleep(600);
	    @localtime = localtime();
	}

	open(O,">$out_log");
	my @files = <${directory}/*ota*fits>;
	foreach my $f (@files) { 
	    my $md5sum = `md5sum $f`;
	    print O $md5sum;
	}
	close(O);
    }
    else {
	print ">> $directory $out_log\n";
    }
    return(0);
}

    


