#!/usr/bin/perl

# safe_convpp - run convpp on a list of files and delete originals
#               if the conversion went OK.

# Get options from command line
#
# -t                  - test (turns on verbose; writes to /dev/null; doesn't delete or use -r if set)
# -v                  - verbose
# -a                  - "archive" - convert runid?.* to: ~/archive/runid?.*.pp
# -o output_directory - use output_directory to put output in...
#                       If you are foolish enough to use both a and o, then o overrides a.
#                       If you use neither, then the current directory is used
# -k                  - keep (don't delete original)
# -r		      - remove the target file first (convpp won't overwrite an existing file)
# -s		      - convert from 64 to 32 bit pp field (via pp64_to_32)
# -T                  - "touch" output files with input to preserve dates
#
# With no options, the file is converted into the current directory

#
# Setup default directories
#
$ARCHIVE=glob "~/archive";

#
# Get options
#
use Getopt::Std;
getopts('Ttvao:ksr');
if ($opt_t) { $opt_v=1; $TT="[testing] "; };
if ($opt_v) { print "Options: verbose: $opt_v, output_directory: $opt_o, archive: $opt_a, test: [$opt_t], keep: [$opt_k], touch: [$out_T]\n" };
if ($opt_k) { $NRO="" } else { $NRO="(not removing original)" };

$Ntried=0;
$Nok=0;

#
# Make sure we can find convpp
#
$junk=`which convpp`;
chomp $junk;
if ($junk =~ /no convpp/) { 
  die "No convpp in path; dying";
} else {
  if ($opt_v) { print "Found convpp OK ($junk)\n" }; 
};

#
# Loop over files for convert
#
while ($F=shift) {

  $Ntried++;
  $Outfile="$F.pp";
  ($Basename)=($F=~/([^\/]*$)/);
  ($Runid)=substr($Basename,0,5);
#
# Set and make output directory (only possible once we have Runid)
#
  $OUTDIR=".";
  if ($opt_a) { $OUTDIR="$ARCHIVE/$Runid" };
  if ($opt_o) { $OUTDIR=$opt_o };
  if (!-d "$OUTDIR") { `mkdir -p "$OUTDIR"` };
  $Outfile="$OUTDIR/$Basename.pp";

  safe_convpp($F,$Outfile);

};

#
# Finished. Optionally say how we got on
#
if ($opt_v) {
  print $TT."Tried to convert $Ntried and succeeded on $Nok\n";
};

#---------------------------------------------------------------

#
# This subroutine runs convpp to convert the fieldsfiles into pp-files
# it checks the conversion has gone OK (checks return status and that
# the message from convpp doesnt contain "error"; also checks that the
# resulting pp-field size is plausible) then deletes (unlink's) the
# fieldsfile.
# If -r is set, it first removes the target file so that convpp doesn't fail.
# If -s is set, it runs the 64-to-32 bit conversion too.
#
sub safe_convpp {
  my($F1,$F2)=@_;
  my($txt,$err);
 
  $S1= -s $F1;
  if ($opt_v) { print $TT."$F1 ($S1) $F2\n" };
  if ($F1 =~/\.pp$/) { print "This is a pp-file! Not converting ($F1)\n"; return };
# Remove target if supplied and -r set
  if ($opt_r and $F2) {
    if ($F1 eq $F2) { print "-r set but target ($F2) equals source ($F1); not removing\n" };
    if ($opt_t) { 
      print "Would have tried to rm $F2 if -t not set\n"
    } else {
      `rm $F2 2> /dev/null`;
    }
  };
  if (!$opt_t) { $txt=`$junk $F1 $F2` } else { $txt=`$junk $F1 /dev/null`; $Nok++; return };
  $err=($? >> 8);
  if ($err or ($txt=~/error/)) {
    print "Problems! [$TT$err] $txt"
  } else {
    if ($opt_s) {
      if ($opt_v) { print "Converting 64 -> 32\n" };
      `pp64_to_32.ksh $F2`;
      ($F2a=$F2)=~s/pp$/32.pp/;
      print `mv $F2a $F2`
    };
    $S2 = -s $F2; if ($S2 eq "") { $S2="0" };
    if ($opt_T) { `touch -r $F1 $F2` };
    if ($S2 > $F1 / 3) {
      if ($opt_v) { print "$TT$F1 converted to $F2 ($S2) OK; will remove $F1$ NRO\n" };
      unlink $F1 unless ($opt_t or $opt_k);
      $Nok++;
    } else {
      print $TT."Thought $F1 converted to $F2 but size is odd: $S2 $NRO\n"
    };
  };
}; 
