#!/usr/bin/perl -w
#< find-dirs.pl - find directories, containing a file, or file mask
use strict;
use warnings;
use File::Basename;
use Cwd;
use File::stat;
unshift(@INC, '/home/geoff/bin');
require "logfileu.pl" or die "ERROR: Unable to load logfileu.pl";
# log file stuff
our ($LF);
my $pgmname = $0;
if ($pgmname =~ /\//) {
   my @tmpsp = split(/\//,$pgmname);
   $pgmname = $tmpsp[-1];
}
my $outfile = "/tmp/temp.".$pgmname.".txt";
open_log($outfile);

my $in_dir = '.';
my %dir_hash = ();

my @warnings = ();

my %done_dirs = ();
my $total_dir_count = 0;
my $max_dirs = 10000;

my %exclude_dirs = (
   '.svn' => 1,
   '.git' => 2,
   'CVS' => 3,
   'xmlrpc-c' => 4,
   'Scenery-1.0.1' => 5
   );

# debug
my $dbg01 = 0; # show each directory processed...
my $dbg02 = 0; # show sub-directory processed...

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" );
   }
}

sub pgm_exit($$) {
   my ($val,$msg) = @_;
   prt($msg) if (length($msg));
   exit($val);
}

sub is_my_file_type($) {
   my ($f) = shift;
   if (($f =~ /\.btg\.gz$/)||($f =~ /\.btg$/)) {
      return 1;
   }
   return 0;
}

sub get_max_len_stg($$) {
   my ($tx,$max) = @_;
   my $len = length($tx);
   if (($len + 3) > $max) {
      my $half = $max / 2;
      $tx = substr($tx,0,$half).'...'.substr($tx,($len - $half));
   }
   return $tx;
}


sub process_dir($$$) {
   my ($dir,$rdh,$lev) = @_;
   my @dirs = ();
   my ($itm,$dr,@files,$ff,$cnt,$sdir);
   my ($tm, $ptm, $sb);
   if (opendir( DIR, $dir )) {
      $total_dir_count++;
      prt( "Done $total_dir_count directories...\n" ) if (($total_dir_count % $max_dirs) == 0);
      prt( "[dbg01] Got dir [$dir] open... processing...\n" ) if ($dbg01);
      @files = readdir(DIR);
      closedir(DIR);
      $dr = $dir;
      $dr .= '/' if ( !($dr =~ /\/$/) );
      foreach $itm (@files) {
         next if (($itm eq '.')||($itm eq '..'));
         $ff = $dr.$itm;
         if ( -d $ff ) {
            if ( ! defined $exclude_dirs{$itm} ) {
               if ( ! defined $done_dirs{$ff} ) {
                  $done_dirs{$ff} = 1;
                  push(@dirs,$ff);
               }
            }
         } else {
            if (is_my_file_type($itm)) {
               $tm = 0;
               if ($sb = stat($ff)) {
                  $tm = $sb->mtime;
               }
               if (defined ${$rdh}{$dir}) {
                  $ptm = ${$rdh}{$dir};
                  if ($tm && ($tm > $ptm)) {
                     ${$rdh}{$dir} = $tm;
                  }
               } else {
                  ${$rdh}{$dir} = $tm;
               }            
            }
         }
      }
   } else {
      prtw("WARNING: Unable to open folder [$dir]... $!...\n");
   }
   if (@dirs) {
      $cnt = scalar @dirs;
      $sdir = get_max_len_stg($dir,60);
      prt( "[$dbg02] $lev: Found $cnt subs in [$sdir]...\n" ) if ($dbg02);
      foreach $itm (@dirs) {
         process_dir($itm,$rdh,($lev + 1));
      }
   }
   return $rdh;
}

sub blank_while_same($$) {
   my ($tx,$sm) = @_;
   my ($len,$len2,$i,$cc,$ntxt,$i2,$last);
   $len = length($sm);
   $len2 = length($tx);
   $len = $len2 if ($len2 < $len);
   $ntxt = '';
   $i2 = 0;
   $last = '';
   for ($i = 0; $i < $len; $i++) {
      $cc = substr($tx,$i,1);
      if ($cc ne substr($sm,$i,1)) {
         # try to adjust back to last full directory
         $ntxt = substr($ntxt,0,$i2).$last;
         last;
      }
      $ntxt .= ' ';  # fill in spaces only
      if ($cc eq '/') {
         $last = $cc;
         $i2 = $i;
      } else {
         $last .= $cc;
      }
   }
   if ($i < $len2) {
      $ntxt .= substr($tx,$i);
   }
   return $ntxt;
}

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

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

sub show_dir_ref($) {
   my ($rdh) = @_;
   my ($dir,$cnt,$same,$itm,$tm,$ctm,@lt,$min,$len,@time,@stime,$i);
   $cnt = scalar keys(%{$rdh});
   prt( "Found BTG files in $cnt directories... sorted alphabetically...\n" );
   $same = '';
   $min = 0;
   @time = ();
   foreach $dir (keys %{$rdh}) {
      $len = length($dir);
      $min = $len if ($len > $min);
   }
   # prt( "Min length is $min...\n" );
   foreach $dir (sort keys %{$rdh}) {
      $tm = ${$rdh}{$dir};
      @lt = localtime($tm);
      $ctm = sprintf( "%02d/%02d/%04d %02d:%02d", $lt[3], $lt[4]+1, $lt[5]+1900, $lt[2], $lt[1] );
      $itm = blank_while_same($dir,$same);
      $itm .= ' ' while (length($itm) < $min);
      prt("$itm $ctm\n");
      $same = $dir;
      push(@time, [$tm,$dir]);
   }
   prt( "Shown $cnt BTG file directories... " );
   @stime = sort mycmp_ascend @time;
   $cnt = scalar @stime;
   prt( "now $cnt in date order...\n" );
   for ($i = 0; $i < $cnt; $i++) {
      $tm = $stime[$i][0];
      @lt = localtime($tm);
      $ctm = sprintf( "%02d/%02d/%04d %02d:%02d", $lt[3], $lt[4]+1, $lt[5]+1900, $lt[2], $lt[1] );
      $itm = $stime[$i][1];
      $itm .= ' ' while (length($itm) < $min);
      prt("$itm $ctm\n");
   }
   prt( "Done $cnt BTG file directories...\n" );
}

#########################################
###### MAIN ######
my $dh = process_dir($in_dir, \%dir_hash, 0);
prt( "Done $total_dir_count directories. Showing results...\n" );
show_dir_ref($dh);
pgm_exit(0,"Normal exit\n");

####################################

# eof - find-dirs.pl
