#!/perl -w
# NAME: cvstime.pl
# AIM: To examine an input directory, seeking CVS folders and files,
# and reporting when the last update was done.
# 15/08/2007 - geoff mclane - geoffair.net/mperl
# SEE cvsversion.pl for the latest, and greatest ;=))
use strict;
use warnings;
use File::stat; # to get the file date
use File::Basename;
### prt( "$0 ... Hello, World ...\n" );
my $in_folder = 'C:/FGCVS/xmlrpc-c';
###my $in_folder = 'C:/FGCVS/Tidy';
my @fnd_files = ();
my @fnd_cvs = ();
my %cvs_names = ();

my ($fcnt, $ccnt, $msg);
my $mxlen = 0;
my $mxsiz = 0;
my $szlen = 0;
my $latest = 0;
my $largest = 0;

# debug
my $dbg1 = 0;	# show processing folders ...
my $dbg2 = 0;	# show CVS/SVN file entries
my $dbg3 = 0;	# show CVS/SVN file types

parse_args(@ARGV);

prt( "Processing $in_folder ...\n" );
process_dir( $in_folder );
$fcnt = scalar @fnd_files;
$ccnt = scalar @fnd_cvs;
prt( "Found $fcnt files, $ccnt in CVS/SVN folders ...\n" );
for (my $i = 0; $i < $ccnt; $i++) {
	my $ff = $fnd_cvs[$i][0];
	my $sz = $fnd_cvs[$i][2];
	my $sf = substr($ff, (length($in_folder) + 1));
	my $len = length($sf);
	if ($len > $mxlen) {
		$mxlen = $len;
	}
	if ($sz > $mxsiz) {
		$mxsiz = $sz;
	}
}
$msg = get_nn($mxsiz);
$szlen = length($msg) + 1;

for (my $i = 0; $i < $ccnt; $i++) {
	my $ff = $fnd_cvs[$i][0];
	my $tm = $fnd_cvs[$i][1];
	my $sz = $fnd_cvs[$i][2];
	my $sf = substr($ff, (length($in_folder) + 1));
	###my ($nm, $dir, $ext) = fileparse( $sf, qr/\.[^.]*/ );
	my ($nm, $dir) = fileparse( $sf );
	if (defined $cvs_names{$nm}) {
		$cvs_names{$nm}++;
	} else {
		$cvs_names{$nm} = 1;
	}
	if ($sz > $largest) {
		$largest = $sz;
	}
	my $nsz = get_nn($sz);
	while(length($nsz) < $szlen) {
		$nsz = ' ' . $nsz;
	}
	$msg = $sf;
	while(length($msg) < $mxlen) {
		$msg .= ' ';
	}
	if ($tm > $latest) {
		$latest = $tm;
	}
	prt( "$msg ". localtime($tm). " $nsz\n" ) if ($dbg2);
}

foreach my $key (keys %cvs_names) {
	my $val = $cvs_names{$key};
	prt( "$key $val\n" ) if ($dbg3);
}

my $nsz = get_nn($largest);
while(length($nsz) < $szlen) {
	$nsz = ' ' . $nsz;
}
$msg = "Latest (largest)";
##while(length($msg) < $mxlen) {
##	$msg .= ' ';
##}
prt( "$msg ". localtime($latest). " $nsz\n" );
exit(0);
##########################
##### subs
sub prt {
	my ($m) = shift;
	print $m;
}

sub mydie {
	my ($m) = shift;
	die $m;
}

sub process_dir {
	my ($inf) = shift;
	prt( "Processing $inf folder ...\n" ) if ($dbg1);
	if ( opendir( DIR, $inf ) ) {
		my @files = readdir(DIR);
		closedir DIR;
		foreach my $fl (@files) {
			if (($fl eq '.') || ($fl eq '..')) {
				next;
			}
			my $ff = $inf . "/" . $fl;
			if (-d $ff) {
				process_dir( $ff );
			} else {
				my $sb = stat($ff);
				if (($ff =~ /\/CVS\//i)||($ff =~ /\/\.svn\//i)) {
					push(@fnd_cvs, [$ff, $sb->mtime, $sb->size ] );
				} else {
					push(@fnd_files, [$ff, $sb->mtime, $sb->size ] );
				}
			}
		}
	} else {
		prt( "WARNING: Can NOT open $inf ... $! ...\n" );
	}
}

sub give_help {
	prt( "$0 [OPTIONS] in_folder\n" );
	prt( "OPTIONS:\n" );
	prt( " -? or -h - This brief help.\n" );
	prt( " -d1      - show processing folders.\n" );
	prt( " -d2      - show CVS/SVN file entries.\n" );
	prt( " -d3      - show CVS/SVN file types.\n" );
	mydie("In folder must exist ...\n");
}

sub parse_args { # @ARGV
	my (@av) = @_;
	while (@av) {
		my $arg = $av[0];
		if (substr($arg,0,1) eq '-') {
			if (($arg eq '-?')||($arg eq '-h')) {
				give_help();
			} elsif ($arg eq '-d1') {
				$dbg1 = 1;
				prt( "Show folder processing ...\n" );
			} elsif ($arg eq '-d2') {
				$dbg2 = 1;
				prt( "Show CVS/SVN file entries ...\n" );
			} elsif ($arg eq '-d3') {
				$dbg3 = 1;
				prt( "Show CVS/SVN file types ...\n" );
			} else {
				mydie( "ERROR: Unknown option [$arg] ... aborting ...\n" );
			}
		} else {
			# bare item - assume INPUT folder
			$in_folder = dos_2_unix($arg);
			prt( "Set in folder to $in_folder ...\n" );
		}

		shift @av;
	}
}

sub dos_2_unix($) {
	my ($du) = shift;
	$du =~ s/\\/\//g;
	return $du;
}

##################################################
# My particular 'nice number'
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)), ($mod+(3*$i)+3) );
			} else {
				$ret .= ',' . substr( $n, ($mod+(3*$i)), ($mod+(3*$i)+3) );
			}
		}
		return $ret;
	}
	return $n;
}

# eof - cvstime.pl
