#! /usr/local/bin/perl -w

use Getopt::Std;
use DateTime;
use PS::IPP::Config;

getopts('ND:M:',\%opt);

my $ipprc = PS::IPP::Config->new("GPC1");
my $nebcon = $ipprc->nebulous();


my $datestring;
if (exists($opt{D})) {
    $datestring = $opt{D};
}
else {
    my @lt = gmtime;
    my $dt = DateTime->now;
    $dt->subtract( days => $lt[6] );
    $datestring = $dt->ymd;
}

my $summary_file = "neb:///ipp_diskspace/${datestring}/summary.dat";
my $S_real_file = $ipprc->file_resolve($summary_file);
open(S,$S_real_file) || die "Cannot find summary.dat\n";

while (<S>) {
    chomp;
    unless ($_ =~ /^#/) {
	($stage_product,$size_in_gb,$count) = split /\s+/;
	($stage,$product) = split /_/, $stage_product;

	$size{$stage}{$product} = $size_in_gb;
	$stage_min{$stage} += $size_in_gb;
	$diskcount{$stage}{$product} = $count;
	$total += $size_in_gb;
    }
}
close(S);

$diskcount{"EXTERNAL"}{"UNKNOWN"} = 1;

my $count_file = "neb:///ipp_diskspace/${datestring}/run_im_counts.dat";
my $C_real_file = $ipprc->file_resolve($count_file);
open(C,$C_real_file) || die "Cannot find run_counts.dat\n";
while(<C>) {
    chomp;
    unless ($_ =~ /^#/) {
	($stage,$state,$N) = split /\s/;
	if ($state eq '') {
	    $state = 'NULL';
	}
	$count{$stage}{$state} = $N;
    }
}
close(C);

my $mappings_file = "neb:///ipp_diskspace/mappings_im.dat";
my $M_real_file = $ipprc->file_resolve($mappings_file);
if (exists($opt{M})) {
    $M_real_file = $opt{M};
}
open(M,$M_real_file) || die "Cannot find mappings.dat\n";
while (<M>) {
    chomp;
    unless ($_ =~ /^#/) {
	($stage,$product,$state,$mult) = split /\s+/;
	if (defined($mult)&&($mult !~ /^$/)) {
	    $map{$stage}{$product}{$state} = $mult;
	}
	else {
	    $map{$stage}{$product}{$state} = 1;
	    if ($stage eq 'RAW' && $product eq 'FITS') {
		if (($state eq 'full')||($state eq 'pending_burntool')||($state eq 'keep')||($state eq 'compressed')||($state eq 'error_compressed')||
		    ($state eq 'goto_lossy')||($state eq 'check_burntool')) {
		    $map{$stage}{$product}{$state} = 2;
		}
	    }
	}
    }
}
close(M);

foreach $stage (keys (%size)) {
    foreach $state (keys (%{ $count{$stage} })) {
	foreach $product (keys (%{ $size{$stage} })) {
	    unless (exists($map{$stage}{$product}{$state})) {
		$map{$stage}{$product}{$state} = 0;
	    }
	}
    }
}

foreach $stage (keys (%size)) {
    foreach $state (keys (%{ $count{$stage} })) {
	$VpN{$stage}{$state} = 0;
	foreach $product (keys (%{ $size{$stage} })) {
	    $N{$stage}{$product} += $count{$stage}{$state}; # $map{$stage}{$product}{$state} * $count{$stage}{$state};
	}		
    }
    foreach $product (keys (%{ $size{$stage} })) {
	foreach $state (keys (%{ $count{$stage} })) {
	    if ($N{$stage}{$product} > 0) {
		$VpN{$stage}{$state} += $size{$stage}{$product} / $N{$stage}{$product};#$map{$stage}{$product}{$state} * $size{$stage}{$product} / $N{$stage}{$product};
		$DVpN{$stage}{$state} += $map{$stage}{$product}{$state} * $size{$stage}{$product} / $diskcount{$stage}{$product};
	    }
#	    print STDERR ">>$stage $product $state $map{$stage}{$product}{$state} $N{$stage}{$product} $count{$stage}{$state} $size{$stage}{$product} $VpN{$stage}{$state}\n";	    
	}
    }
}

my $out_fh;

if (exists($opt{N})) {
#     my $dt = DateTime->now;

#     my @lt = gmtime;
#     my $dt_data = DateTime->now;
#     $dt->subtract( days => $lt[6]);
#     my $datestring = $dt->ymd;

    my $ipprc = PS::IPP::Config->new("GPC1");
    my $nebcon = $ipprc->nebulous();

    my $outfile = "neb:///ipp_diskspace/${datestring}/usage_report.dat";

    if ($ipprc->file_exists($outfile)) {
        my $U_file = $ipprc->file_resolve($outfile);
        open($out_fh,">$U_file");
    }
    else {
        $out_fh = $ipprc->file_create_open($outfile);
    }
}

foreach $stage (sort (keys %VpN)) {
    $measuredA = 0;
    $measuredB = 0;
    foreach $state (sort (keys %{ $VpN{$stage} })) {
	unless(exists($count{$stage}{$state})) {
	    $count{$stage}{$state} = 0;
	}
	$V = $VpN{$stage}{$state} * $count{$stage}{$state};

	if ($stage eq 'RAW') {
	    $label = "PERMANENT";
	}
	elsif ($stage eq 'EXTERNAL') {
	    $label = 'EXTERNAL';
	}
	else {
	    if (($state eq 'goto_cleaned')||
		($state eq 'goto_purged')||
		($state eq 'goto_scrubbed')||
		($state eq 'update')) {
		$label = "TRANSIENT";
	    }
	    elsif (($state eq 'full')&&(
		       ($stage eq 'CHIP')||
		       ($stage eq 'WARP')||
		       ($stage eq 'DIFF')||
		       ($stage eq 'DIST')||
		       ($stage eq 'DESTREAK')
		   )) {
		$label = 'TRANSIENT';
	    }
	    else {
		$label = 'PRODUCT';
	    }
	}
	$labels{$label} += $V;
	$alt_labels{$label} += $DVpN{$stage}{$state} * $count{$stage}{$state};
	$measuredA += $V;
	$measuredB += $DVpN{$stage}{$state} * $count{$stage}{$state};
	printf("%-8s %-18s %-10s\t%14.4f %12.6f\t%14.6f %12.6f\t%9d\n",
		$stage,$state,$label,$V,$VpN{$stage}{$state},$DVpN{$stage}{$state} * $count{$stage}{$state},$DVpN{$stage}{$state},$count{$stage}{$state});
	if (exists($opt{N})) {
	    printf($out_fh "%-8s %-18s %-10s\t%14.4f %12.6f\t%14.6f %12.6f\t%9d\n",
		   $stage,$state,$label,$V,$VpN{$stage}{$state},$DVpN{$stage}{$state} * $count{$stage}{$state},$DVpN{$stage}{$state},$count{$stage}{$state});
	}
    }
    printf("%-8s %-18s %-10s\t%14.4f %-12s\t%14.6f\n",
	   $stage,"","MINIMUM",$stage_min{$stage},"",$stage_min{$stage});
    printf("%-8s %-18s %-10s\t%14.4f %-12s\t%14.6f\n",
	   $stage,"","MEASURED",$measuredA,"",$measuredB);
    if (exists($opt{N})) {
	printf($out_fh "%-8s %-18s %-10s\t%14.4f %-12s\t%14.6f\n",
	       $stage,"","MINIMUM",$stage_min{$stage},"",$stage_min{$stage});
    }
}
$sum = 0;
foreach $l (keys %labels) {
    $sum += $labels{$l};
    $alt_sum += $alt_labels{$l};
    print STDERR "\t$l  \t$labels{$l}\t$alt_labels{$l}\n";
    if (exists($opt{N})) {
	print $out_fh "\t$l  \t$labels{$l}\t$alt_labels{$l}\n";
    }
}
print STDERR "\tTOTAL    \t$sum\t$alt_sum\n";
print STDERR "\tEXP_TOT  \t$total\n";

if (exists($opt{N})) {
    print $out_fh "\tTOTAL    \t$sum\t$alt_sum\n";
    print $out_fh "\tEXP_TOT  \t$total\n";
    close($out_fh);
}
