#!/usr/bin/perl -w

# Copyright 2005, 2010 Hewlett-Packard Development Company, LP
#
# this software may be copied only under the terms of either the Artistic License
# or the GNU General Public License, which may be found in the source kit

# Debug Flag
# 1 - show interesting stuff
# 2 - call collectl with -d1 switch
# 4 - don't execute collectl command (only makes sense with 1 and/or 2)
# 8 - show root of file being processed

use strict;
use Getopt::Long;
use File::Basename;

my $Copyright='Copyright 2005 Hewlett-Packard Development Company, L.P.';

my ($Version, $colbin, $debug, $forceFlag, $helpFlag, $hosts, $inDir, $outDir);
my ($fromDate, $thruDate, $subsys, $uniqueFlag);

#defaults
$Version='V1.3.1';
$Version.='';  # get rid of -w warning
$fromDate='20050101';
$debug=$forceFlag=0;
$inDir='/var/log/collectl';
$colbin=(-e '/usr/sbin/collectl') ? '/usr/sbin/collectl' : '/usr/bin/collectl';
GetOptions("colbin=s"   => \$colbin,
	   "debug=i"    => \$debug,
	   "force!"     => \$forceFlag,
	   "help!"      => \$helpFlag,
	   "hosts=s"    => \$hosts,
	   "indir=s"    => \$inDir,
	   "outdir=s"   => \$outDir,
	   "fromdate=s" => \$fromDate,
	   "thrudate=s" => \$thruDate,
	   "subsys=s"   => \$subsys,
	   "unique!"    => \$uniqueFlag
	   ) or error("type -help for help");

usage()    if defined($helpFlag);

my ($day, $mon, $year, $yesterday, $today);
($day, $mon, $year)=(localtime(time))[3..5];
$today=sprintf("%d%02d%02d", $year+1900, $mon+1, $day);
($day, $mon, $year)=(localtime(time-86400))[3..5];
$yesterday=sprintf("%d%02d%02d", $year+1900, $mon+1, $day);

$thruDate=$today        if !defined($thruDate);
$thruDate=$yesterday    if $thruDate=~/yesterday/i;
$fromDate=$yesterday    if $fromDate=~/yesterday/i;

my $colOpts=($uniqueFlag) ? '-ouz' : '-ocz';

error("-outdir required")          if !defined($outDir);
error("$inDir does not exist")     if !-e $inDir;
error("$outDir does not exist")    if !-e $outDir;
error("invalid Date: $fromDate")   if defined($fromDate) && !dateCheck($fromDate);
error("invalid Date: $thruDate")   if defined($thruDate) && !dateCheck($thruDate);

my @matchHosts=split(/[, ]+/, $hosts)    if defined($hosts);

my $matches=0;
my (%count, %processed);
opendir DIR, $inDir or error("Couldn't open '$inDir'");
while (my $file=readdir(DIR))
{
  next    if $file!~/(.*)-(\d{8})-\d{6}\.raw/;
  my $hostname=$1;
  my $filedate=$2;

  next    if $filedate<$fromDate || $filedate>$thruDate;

  if (defined($hosts))
  {
    my $match=0;
    foreach my $hostMatch (@matchHosts)
    {
      if ($hostname=~/$hostMatch/)
      {
	$match=1;
	last;
      }
    }
    next    if !$match;
  }
  $matches++;

  # if we've already processed this file (there could be multiple ones for a
  # single day), we're done with it since the collectl command says to process
  # all files with the same root.
  $file=~/(.*)-\d{6}\..*/;
  my $inFileRoot=$1;
  print "Inspecting root: $inFileRoot\n"    if $debug & 8;
  $count{$inFileRoot}++;
  next    if $processed{$inFileRoot};

  my $inFileName="$inDir/$file";
  my $inFileModTime=(stat($inFileName))[9];

  # That said, if a 'tab' file already exists and it's older than the raw
  # file, generate new files.
  my $outFileName="$outDir/$inFileRoot.tab";
  if (-e $outFileName && !$forceFlag)
  {
    my $outFileModTime=(stat($outFileName))[9];
    next    if $outFileModTime>$inFileModTime;
    print "$outFileName already exists but is older than $inFileName\n"
	    if $debug & 1;
  }
 
  # There might be more than one raw file, but using wildcarding below
  # we only want to process one of them.  Be sure to use -w to force wide
  # output for proc data which is not by default.
  $processed{$inFileRoot}++;
  print "Generating plot file(s) for '$inDir/$inFileRoot*'\n";
  my $command="$colbin -p \"$inDir/$inFileRoot*\" -P -f $outDir -w $colOpts";
  $command.=" -s $subsys"        if defined($subsys);
  $command.=" -d1"               if $debug & 2;
  print "Command: $command\n"    if $debug & 1;
  `$command`                     unless $debug & 4;
}

error("no files matching files found")    if !$matches;

sub dateCheck
{
  return(1);
}

sub error
{
  print "$_[0]\n";
  exit;
}

sub usage
{
  print "usage: genplotfile.pl -outdir dirname [switches]\n";
  print "  -colbin   path   path to collectl if not in user's path\n";
  print "  -debug    num    prints debugging info, see source for details\n";
  print "  -force           always generate plot file from raw files\n";
  print "  -help            print this text\n";
  print "  -hosts    list   if specified (comma or space separated), only\n";
  print "                   those files that match at least one string\n";
  print "                   will be processed\n";
  print "  -indir    dir    read files from this directory [default=/var/log/collectl]\n";
  print "  -outdir   dir    write plotfiles to this directory\n";
  print "  -fromdate date   only process files >= date\n";
  print "  -thrudate date   only process files <= date\n";
  print "  -subsys   str    use this as the value for -s in collectl\n";
  print "  -unique          pass the 'u' option to collectl to create 1\n";
  print "                   playback file per raw date file\n";

  print "$Copyright\n";
  exit;
}
