#!/perl -w
# NAME: chkaircraft.pl
# AIM: VERY SPECIFIC - Scan the given FG data\Aircraft folder for items in
# @air_list, and write a list of all other NOT listed...
# 04/07/2010 geoff mclane http://geoffair.net/mperl
use strict;
use warnings;
use File::Basename;  # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[.]*/] )
use Cwd;
use File::stat;
unshift(@INC, 'C:\GTools\perl');
require 'logfile.pl' or die "Unable to load logfile.pl ...\n";
# log file stuff
my ($LF);
my $pgmname = $0;
if ($pgmname =~ /\w{1}:\\.*/) {
    my @tmpsp = split(/\\/,$pgmname);
    $pgmname = $tmpsp[-1];
}
my $perl_dir = 'C:\GTools\perl';
my $outfile = $perl_dir."\\temp.$pgmname.txt";
open_log($outfile);

# for in editor runs only
my $debug_on = 0;
my $def_dir = 'C:\FG\28\data';

# user variables
my $load_log = 1;
my $in_file = '';
my $block = 4096;
my $show_sorted = 1;

my @air_org_list = qw( 777-200 A6M2 b1900d bo105 c172p CitationX dhc2 Dragonfly
    f-14b Generic Instruments Instruments-3d j3cub SenecaII sopwithCamel ufo UIUC ZLT-NT );
my @air_list = qw( 777-200 A6M2 b1900d bo105 c172p CitationX dhc2 Dragonfly
    f-14b Generic Instruments Instruments-3d Cub SenecaII sopwithCamel ufo UIUC ZLT-NT );

### program variables
my @warnings = ();
my $cwd = cwd();
my $os = $^O;

sub pgm_exit($$) {
    my ($val,$msg) = @_;
    if (length($msg)) {
        $msg .= "\n" if (!($msg =~ /\n$/));
        prt($msg)
    }
    close_log($outfile,$load_log);
    exit($val);
}


sub prtw($) {
   my ($tx) = shift;
   $tx =~ s/\n$//;
   prt("$tx\n");
   push(@warnings,$tx);
}

sub show_warnings() {
   if (@warnings) {
      prt( "\nGot ".scalar @warnings." WARNINGS...\n" );
      foreach my $itm (@warnings) {
         prt("$itm\n");
      }
      prt("\n");
   } else {
      prt( "\nNo warnings issued.\n\n" );
   }
}

#string dirghtml::b2ks1(double d) // b2ks1(double d)
sub bytes2ks($) {
	my ($d) = @_;
	my $oss;
	my $kss;
	my $lg = 0;
	my $ks = ($d / 1024); #// get Ks
	my $div = 1;
   if( $ks < 1024 ) {
      $div = 1;
      $oss = "KB";
   } elsif ( $ks < (1024 * 1024) ) {
	  $div = 1024;
      $oss = "MB";
   } elsif ( $ks < (1024 * 1024 * 1024) ) {
      $div = (1024 * 1024);
      $oss = "GB";
   } else {
      $div = (1024 * 1024 * 1024);
      $oss = "TB";
   }
   $kss = $ks / $div;
   $kss += 0.05;
   $kss *= 10;
   $lg = int($kss);
   return( ($lg / 10) . $oss );
}

sub get_nn($) { # perl nice number nicenum add commas
	my ($n) = shift;
	if (length($n) > 3) {
		my $mod = length($n) % 3;
		my $ret = (($mod > 0) ? substr( $n, 0, $mod ) : '');
		my $mx = int( length($n) / 3 );
		for (my $i = 0; $i < $mx; $i++ ) {
			if (($mod == 0) && ($i == 0)) {
				$ret .= substr( $n, ($mod+(3*$i)), 3 );
			} else {
				$ret .= ',' . substr( $n, ($mod+(3*$i)), 3 );
			}
		}
		return $ret;
	}
	return $n;
}

sub mycmp_decend {
   if (${$a}[0] < ${$b}[0]) {
      return 1;
   }
   if (${$a}[0] > ${$b}[0]) {
      return -1;
   }
   return 0;
}

sub mycmp_ascend {
   return 1 if (${$a}[0] > ${$b}[0]);
   return -1 if (${$a}[0] < ${$b}[0]);
   return 0;
}

sub is_in_list($) {
    my ($dir) = @_;
    my ($itm);
    foreach $itm (@air_list) {
        return 1 if ($itm eq $dir);
    }
    return 0;
}

sub get_missed_list($) {
    my ($ra) = @_;
    my ($itm,$dir,$cnt,$i,$fnd);
    $cnt = scalar @{$ra};
    my $missed = '';
    foreach $itm (@air_list) {
        $fnd = 0;
        for ($i = 0; $i < $cnt; $i++) {
            $dir = ${$ra}[$i][0];
            if ($itm eq $dir) {
                $fnd = 1;
                last;
            }
        }
        if (!$fnd) {
            $missed .= ' ' if (length($missed));
            $missed .= $itm;
        }
    }
    return $missed;
}

sub get_dir_size($$$$);

sub get_dir_size($$$$) {
    my ($dir,$rrs,$ras,$rssx) = @_;
    my $rsize = 0;
    my $asize = 0;
    my $ss = 0;
    if (!opendir(DIR,$dir)) {
        pgm_exit(1,"ERROR: Can NOT open directory [$dir]!\n");
    }
    my @files = readdir(DIR);
    closedir(DIR);
    my ($item,$ff,$sb,$sz,$blks,$asz);
    foreach $item (@files) {
        if (($item eq '.')||($item eq '..')) {
            $asize += $block;
            next;
        }
        $ff = "$dir\\$item";
        if (-d $ff) {
            get_dir_size($ff,$rrs,$ras,$rssx);
        } elsif (-f $ff) {
            if ($sb = stat($ff)) {
                $sz = $sb->size;
                if ($sz == 0) {
                    $blks = 1;
                } else {
                    $blks = int($sz / $block);
                    $blks++ if ($sz % $block);
                }
                $asz = $blks * $block;
                $rsize += $sz;
                $asize += $asz;
                $ss++ if ($item =~ /-set\.xml$/);
            } else {
                prtw("WARNING: Unable to 'stat' [$ff]!\n");
            }
        }
    }
    ${$rrs} += $rsize;
    ${$ras} += $asize;
    ${$rssx} += $ss;
}

my $dbg01 = 0;

sub process_aircraft($) {
    my ($inf) = @_;
    if (!opendir(DIR,$inf)) {
        pgm_exit(1,"ERROR: Can NOT open directory [$inf]!\n");
    }
    my @files = readdir(DIR);
    closedir(DIR);
    my $icnt = scalar @files;
    prt("Processing $icnt items, from [$inf]\n");
    my ($item,$fnd,$dir,$cnt,$incnt,$xcnt,$i);
    $fnd = 0;
    my @dirs = ();
    my @indirs = ();
    my @exclude = ();
    my %hash = ();
    $incnt = 0;
    $xcnt = 0;
    foreach $item (@files) {
        next if (($item eq '.')||($item eq '..'));
        $dir = "$inf\\$item";
        if (-d $dir) {
            push(@dirs,$dir);
            if (is_in_list($item)) {
                push(@indirs,[$item,$dir,0,0]);
                $incnt++;
            } else {
                push(@exclude,[$item,$dir,0,0]);
                $xcnt++;
            }
            $fnd++;
        }
    }
    $cnt = scalar @air_list;
    prt("Found $fnd dirs, in [$inf], $incnt of $cnt per list, exclude $xcnt\n");
    if ($cnt > $incnt) {
        $item = get_missed_list(\@indirs);
        prt("Missed [$item]\n");
    }
    my $rsize = 0;
    my $asize = 0;
    my $itotrsize = 0;
    my $itotasize = 0;
    my $ototrsize = 0;
    my $ototasize = 0;
    my ($key,$seenset,$setcnt);
    my @inarr = ();
    my @outarr = ();
    # IN group
    $setcnt = 0;
    for ($i = 0; $i < $incnt; $i++) {
        $item = $indirs[$i][0];
        $dir  = $indirs[$i][1];
        $rsize = 0;
        $asize = 0;
        $seenset = 0;
        get_dir_size($dir,\$rsize,\$asize,\$seenset);
        $itotrsize += $rsize;
        $itotasize += $asize;
        $key = "IN $dir";
        $hash{$key} = [$rsize,$asize,$seenset];
        prt( "$key $rsize $asize\n" ) if ($dbg01);
        push(@inarr, [$rsize, $asize, $key, $seenset]);
        $setcnt++ if ($seenset);
    }
    
    $key = "IN *TOTALS*";
    $hash{$key} = [$itotrsize,$itotasize,$setcnt];
    prt( "$key $itotrsize $itotasize $setcnt\n" );
    @inarr = sort mycmp_ascend @inarr;
    push(@inarr, [$itotrsize,$itotasize,$key,$setcnt]);
    $key = "*ARRAY IN*";
    $hash{$key} = [@inarr];

    # OUT group
    $setcnt = 0;
    for ($i = 0; $i < $xcnt; $i++) {
        $item = $exclude[$i][0];
        $dir  = $exclude[$i][1];
        $rsize = 0;
        $asize = 0;
        $seenset = 0;
        get_dir_size($dir,\$rsize,\$asize,\$seenset);
        $ototrsize += $rsize;
        $ototasize += $asize;
        $key = "OUT $dir";
        prt( "$key $rsize $asize\n" ) if ($dbg01);
        $hash{$key} = [$rsize,$asize,$seenset];
        push(@outarr, [$rsize,$asize,$key,$seenset]);
        $setcnt++ if ($seenset);
    }
    $key = "OUT *TOTALS*";
    $hash{$key} = [$ototrsize,$ototasize,$setcnt];
    prt( "$key $ototrsize $ototasize $setcnt\n" );
    @outarr = sort mycmp_ascend @outarr;
    push(@outarr, [$ototrsize,$ototasize,$key,$setcnt]);
    $key = "*ARRAY OUT*";
    $hash{$key} = [@outarr];
    return \%hash;
}

sub show_ref_hash($) {
    my ($rh) = @_;
    my ($key,$val,$min,$len,$rsz,$asz,$nn,$minr,$mina,$ks,$minrk,$minak);
    $min = 0;
    $minr = 0;
    $mina = 0;
    $minrk = 0;
    $minak = 0;
    foreach $key (keys %{$rh}) {
        next if ($key =~ /^\*ARRAY\s+/);
        $val = ${$rh}{$key};
        $len = length($key);
        $min = $len if ($len > $min);
        $rsz = ${$val}[0];
        $asz = ${$val}[1];
        $nn = get_nn($rsz);
        $len = length($nn);
        $minr = $len if ($len > $minr);
        $nn = get_nn($asz);
        $len = length($nn);
        $mina = $len if ($len > $mina);
        $ks = bytes2ks($rsz);
        $len = length($ks);
        $minrk = $len if ($len > $minrk);
        $ks = bytes2ks($asz);
        $len = length($ks);
        $minak = $len if ($len > $minak);
    }
    my ($nn2,$ks2,$tkey,$i,$set);
    if ($show_sorted) {
        my $key1 = "*ARRAY IN*";
        my $key2 = "*ARRAY OUT*";
        if ( (defined ${$rh}{$key1}) && (defined ${$rh}{$key2}) ) {
            my $rinarr = ${$rh}{$key1};
            my $routarr = ${$rh}{$key2};
            $len = scalar @{$rinarr};
            for ($i = 0; $i < $len; $i++) {
                $rsz = ${$rinarr}[$i][0];
                $asz = ${$rinarr}[$i][1];
                $key = ${$rinarr}[$i][2];
                $set = ${$rinarr}[$i][3];
                $nn = get_nn($rsz);
                $nn2 = get_nn($asz);
                $ks = bytes2ks($rsz);
                $ks2 = bytes2ks($asz);
                $key .= ' ' while (length($key) < $min);
                $nn = " $nn" while (length($nn) < $minr);
                $ks = " $ks" while (length($ks) < $minrk);
                $nn2 = " $nn2" while (length($nn2) < $mina);
                $ks2 = " $ks2" while (length($ks2) < $minak);
                prt("$key $nn ($ks) $nn2 ($ks2) $set\n");
            }
            $len = scalar @{$routarr};
            for ($i = 0; $i < $len; $i++) {
                $rsz = ${$routarr}[$i][0];
                $asz = ${$routarr}[$i][1];
                $key = ${$routarr}[$i][2];
                $set = ${$routarr}[$i][3];
                $nn = get_nn($rsz);
                $nn2 = get_nn($asz);
                $ks = bytes2ks($rsz);
                $ks2 = bytes2ks($asz);
                $key .= ' ' while (length($key) < $min);
                $nn = " $nn" while (length($nn) < $minr);
                $ks = " $ks" while (length($ks) < $minrk);
                $nn2 = " $nn2" while (length($nn2) < $mina);
                $ks2 = " $ks2" while (length($ks2) < $minak);
                prt("$key $nn ($ks) $nn2 ($ks2) $set\n");
            }
            prt("\nList of ".($len - 1)." EXCLUDED directories...\n");
            for ($i = 0; $i < $len; $i++) {
                $rsz = ${$routarr}[$i][0];
                $asz = ${$routarr}[$i][1];
                $key = ${$routarr}[$i][2];
                $set = ${$routarr}[$i][3];
                next if ($key eq 'OUT *TOTALS*');
                $key =~ s/^OUT\s+//;
                prt("$key\\*.*\n");
            }
            return;
        }
        prtw("WARNING: Sort FAILED! Missing key [$key1], or [$key2]! Doing unsorted...\n");
    }
    $tkey = '';
    foreach $key (keys %{$rh}) {
        next if ($key =~ /^\*ARRAY\s+/);
        if ($key eq 'IN *TOTALS*') {
            $tkey = $key;
        } elsif ($key =~ /^IN\s+/) {
            $val = ${$rh}{$key};
            $rsz = ${$val}[0];
            $asz = ${$val}[1];
            $nn = get_nn($rsz);
            $nn2 = get_nn($asz);
            $ks = bytes2ks($rsz);
            $ks2 = bytes2ks($asz);
            $key .= ' ' while (length($key) < $min);
            $nn = " $nn" while (length($nn) < $minr);
            $ks = " $ks" while (length($ks) < $minrk);
            $nn2 = " $nn2" while (length($nn2) < $mina);
            $ks2 = " $ks2" while (length($ks2) < $minak);
            prt("$key $nn ($ks) $nn2 ($ks2)\n");
        }
    }
    if (length($tkey)) {
        $key = $tkey;
        $val = ${$rh}{$key};
        $rsz = ${$val}[0];
        $asz = ${$val}[1];
        $nn = get_nn($rsz);
        $nn2 = get_nn($asz);
        $ks = bytes2ks($rsz);
        $ks2 = bytes2ks($asz);
        $key .= ' ' while (length($key) < $min);
        $nn = " $nn" while (length($nn) < $minr);
        $ks = " $ks" while (length($ks) < $minrk);
        $nn2 = " $nn2" while (length($nn2) < $mina);
        $ks2 = " $ks2" while (length($ks2) < $minak);
        prt("$key $nn ($ks) $nn2 ($ks2)\n");
    } else {
        prtw("WARNING: IN *TOTALS* NOT FOUND!\n");
    }

    $tkey = '';
    foreach $key (keys %{$rh}) {
        next if ($key =~ /^\*ARRAY\s+/);
        if ($key eq 'OUT *TOTALS*') {
            $tkey = $key;
        } elsif ($key =~ /^OUT\s+/) {
            $val = ${$rh}{$key};
            $rsz = ${$val}[0];
            $asz = ${$val}[1];
            $nn = get_nn($rsz);
            $nn2 = get_nn($asz);
            $ks = bytes2ks($rsz);
            $ks2 = bytes2ks($asz);
            $key .= ' ' while (length($key) < $min);
            $nn = " $nn" while (length($nn) < $minr);
            $ks = " $ks" while (length($ks) < $minrk);
            $nn2 = " $nn2" while (length($nn2) < $mina);
            $ks2 = " $ks2" while (length($ks2) < $minak);
            prt("$key $nn ($ks) $nn2 ($ks2)\n");
        }
    }
    if (length($tkey)) {
        $key = $tkey;
        $val = ${$rh}{$key};
        $rsz = ${$val}[0];
        $asz = ${$val}[1];
        $nn = get_nn($rsz);
        $nn2 = get_nn($asz);
        $ks = bytes2ks($rsz);
        $ks2 = bytes2ks($asz);
        $key .= ' ' while (length($key) < $min);
        $nn = " $nn" while (length($nn) < $minr);
        $ks = " $ks" while (length($ks) < $minrk);
        $nn2 = " $nn2" while (length($nn2) < $mina);
        $ks2 = " $ks2" while (length($ks2) < $minak);
        prt("$key $nn ($ks) $nn2 ($ks2)\n");
    } else {
        prtw("WARNING: OUT *TOTALS* NOT FOUND!\n");
    }

}

sub process_in_folder($) {
    my ($inf) = @_;
    if (!opendir(DIR,$inf)) {
        pgm_exit(1,"ERROR: Can NOT open directory [$inf]!\n");
    }
    my @files = readdir(DIR);
    closedir(DIR);
    my $icnt = scalar @files;
    prt("Processing $icnt items, from [$inf]\n");
    my ($item,$fnd,$dir);
    $fnd = 0;
    foreach $item (@files) {
        if ($item =~ /Aircraft/) {
            $fnd = 1;
            last;
        }
    }
    if (!$fnd) {
        pgm_exit(1,"ERROR: Unable to find [$inf/Aircraft]!\n");
    }
    my $ref_hash = process_aircraft($inf."\\Aircraft");
    show_ref_hash($ref_hash);
}

#########################################
### MAIN ###
parse_args(@ARGV);
#prt( "$pgmname: in [$cwd]: Hello, World...\n" );
process_in_folder($in_file);
pgm_exit(0,"Normal exit(0)");
########################################
sub give_help {
    prt("$pgmname: version 0.0.1 2010-07-04\n");
    prt("Usage: $pgmname [options] in_folder\n");

}
sub need_arg {
    my ($arg,@av) = @_;
    pgm_exit(1,"ERROR: [$arg] must have follwoing argument!\n")
        if (!@av);
}
sub parse_args {
    my (@av) = @_;
    while (@av) {
        my $arg = $av[0];
        if ($arg =~ /-/) {
            my $sarg = substr($arg,1);
            $sarg = substr($sarg,1) while ($sarg =~ /-/);
            if (($sarg =~ /h/i)||($sarg eq '?')) {
                give_help();
                pgm_exit(0,"Help exit(0)");
            } else {
                pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            }
        } else {
            $in_file = $arg;
            prt("Set input to [$in_file]\n");
        }
        shift @av;
    }
    if ((length($in_file) == 0) && $debug_on && (-d $def_dir)) {
        $in_file = $def_dir;
        prt("DEBUG_ON: Set input to DEFAULT [$in_file]\n");
    }

    if (length($in_file) == 0) {
        pgm_exit(1,"ERROR: NO input folder found in command!\n");
    }
}

# eof - template.pl
