#!/usr/bin/env perl
##########################################################################
#
# routine: unreserve.pl ( from clnxxx.pl )
#
# purpose: Cleans the data reduction and reservation blackboard of all traces of
#          science processing (files and BB entries) for an OTFR request.
#			  Does NOT clean out the OTFR request directory.  This way the files in
#          an individual OTFR directory can be examined without holding up the
#          processing of another request which requires the same data.
#
#          The *.podlist file is used to obtain a list of exposure
#          names and pod file names.  These are deleted from the
#          data reduction directories.
#
#          NOTE: This routine assumes that the locations of these
#                data reduction directories are specified through
#                resource file entries (hopefully pointing to path
#                mnemonics in the data reduction path).
#
# modification history:
#
#   date     opr     who       reason
# -------- --------  --------- --------------------------------------
# 06/01/00 43165     MSwam     first version
# 03/12/01 43165_05  MSwam     add dan cleanup
# 03/23/01 43165_07  MSwam     cleanup both pod locations and extensions
# 03/29/01 43165_10  MSwam     add cleanup of reservation OSFs
# 04/04/01 43165_11  MSwam     ignore missing .rsvlist file (when flushing)
# 04/18/01 43165_20  MSwam     remove extra asn trailers
# 09/26/01 44293     MSwam     handle multiple OSFs for request (e.g. q/s split)
# 01/23/03           Sherbert  first version (above for clnxxx.pl)
# 08/15/03 47755     Sherbert  get Warning about chmod correct and loose \n's
#                              Add wildcard to get pods left behind
#                              Warn about cleanups that fail in case of problem like above
#                              Clean up with CL=v or CL=w
# 10/22/03 47755     Sherbert  Change spacing to make sdiff w/clnxxx easy
# 01/14/11 67112     MSwam     Remove obsolete commented-out lines
# 
##########################################################################
#
# prepend the Perl include variable using all components of PATH
# (this allows us to reuse other OTFR Perl code)
#
 $PATH  = $ENV{"PATH"};
 @parts = split /:/, $PATH;
 while (defined($val = pop(@parts))) {
    if (substr($val,0,1) eq "/") { unshift(@INC, $val)}
 }
 
#
# include these modules
#
 require 'printmsg.pl';       # prints a formatted status message
 require 'otfr_setup.pl';     # OTFR pipeline set-up for processing a request
 require 'resolve.pl';        # resolves a stretched filespec
 
 print "\n";
 OTFR_setup();
 PrintMsg("I","unreserve: Processing $p_dir");
 
# read the data reduction directory locations from the environment
#   and resolve any stretched env vars
#
 $caldir = Resolve("CALDIR");
 $sisdir = Resolve("SISDIR");
 $pod_in_dir  = Resolve("POD_IN_DIR");
 $pod_out_dir = Resolve("POD_OUT_DIR");
 $path   = $ENV{"DATA_REDUCTION_PATH"};
 $reserve_path = $ENV{"RESERVATION_PATH"};
 
# open the PODLIST file listing exposures and podfile names
 $infile = $p_dir . ".podlist";
 if (!open(PODLIST, "$infile")) {
    PrintMsg("E","ERROR: failed to open infile $infile"); 
    exit $quit_this_dataset;
 }
 
#
# read each podlist entry
#
 while (<PODLIST>) {
   #
   # split the read buffer ($_) into fields and lower case them
   ($exp, $pod, $dontuse_datatype) = split(/ /,$_);  
   $exp_long = lc($exp);
   #
   # trim off last char to avoid problems with matching
   $exp = substr($exp_long, 0, 8);
   $pod = lc($pod);
 
   # fix old-style wf2 pod names
   $pod =~ s/^w/lz_a2_w/;
 
   # clean data reduction pipeline first
   #
   # - remove cal files for this exposure
   @files = glob($caldir . $exp . "*");
   if (scalar(@files)) {
      PrintMsg("I","unlinking cal files: @files");
      my $ok = unlink @files;       ## unlink returns no. of files del'd
      PrintMsg ("I","caldir: $ok files removed ");
      if ( ! $ok ) {
        ## Use warnings as original code didn't check for failures
        PrintMsg ("W","WARNING: Failure unlinking files from $caldir");
      }
   }
 
   # - remove sis files for this exposure
   @files = glob($sisdir . $exp . "*");
   if (scalar(@files)) {
      PrintMsg("I","unlinking sis files: @files");
      my $ok = unlink @files;
      PrintMsg ("I","sisdir: $ok files removed ");
      if ( ! $ok ) {
        PrintMsg ("W","WARNING: Failure unlinking files from $sisdir");
      }
   }
 
   # - remove the pod-whacked POD file from either the input or output dir
   #   (do NOT remove .pod_duplicate entries, since they are still needed
   #    for satisfying another request)
   ## Mike says it is no longer necessary to save duplicates
   ## so I am changing .pod_done to .pod_* so that duplicates and _proc, etc.
   ## are removed
   PrintMsg("I","Remove, if any, pod-whacked PODs from input or output dirs");
   ## Add a wildcard character so delete doesn't fail on 8-char ipppssoot (exp)
   # @files = glob($pod_in_dir . $pod . "_" . $exp . "*.pod_done");
   @files = glob($pod_in_dir . $pod . "_" . $exp . "*.pod_*");
   PrintMsg("D","if scalar \@files, do pod_in_dir stuff.  \@files is @files.");    ## trace
   if (scalar(@files)) {
      PrintMsg("I","unlinking input pod_done's: @files");
      my $ok = unlink @files;
      PrintMsg ("I","pod_in_dir: $ok files removed ");
      if ( ! $ok ) {
        PrintMsg ("W","WARNING: Failure unlinking files from $pod_in_dir");
      }
   }
   ## Pre-pend a wildcard character so delete doesn't fail on 8-char ipppssoot (exp)
   ## Add another wildcard after pod to get *.pod_*
   @files = glob($pod_out_dir . $pod . "_" . $exp . "*.pod*");
   #PrintMsg("I","if scalar \@files, do pod_out_dir stuff.  \@files is @files.");
   if (scalar(@files)) {
      # change POD permissions to allow deletion
      my $ok = chmod 0755, @files;
      if ($ok != 0) {	## Was != 1 but successful exit is 0
         # setting permissions failed
         PrintMsg("W","Failed to set permissions to 0755 for @files");
      }
      PrintMsg("I","unlinking output pods: @files");
      my $ok2 = unlink @files;
      PrintMsg ("I","pod_out_dir: $ok2 files removed ");
      if ( ! $ok2 ) {
        PrintMsg ("W","WARNING: Failure unlinking files from $pod_out_dir");
      }
   }
 
   # - remove the exposure OSF (wildcard needed since the last char is unknown)
   PrintMsg("I","osf_delete -p $path -f $exp'*' ");
   `osf_delete -p $path -f $exp'*'`;
   if ($? != 0) {
      PrintMsg("W","WARNING: Failed to delete OSF for $exp from $path");
      # try looking for multiple OSFs that matched
      PrintMsg ("I", "osf_test -p $path -f '$exp?' -pr dataset ");
      @out = `osf_test -p $path -f '$exp?' -pr dataset`;
      $savestat = $?;
      if ($savestat != 0) {
		PrintMsg("E","ERROR: osf_test failed for $path, $exp; ecode= $savestat");
      }
      elsif (scalar(@out) == 0) {
		PrintMsg("W","WARNING: no OSF found for $path, $exp");
      }
      else {
         # attempt to delete each OSF 
         # (q/s splits could have multiple OSFs in science pipeline)
         for ($i=0; $i < scalar(@out); $i++) {
             $temp = $out[$i];
             # remove newline
             chomp($temp);
             PrintMsg("I","Attempting osf_delete -p $path -f $temp");
             `osf_delete -p $path -f $temp`;
         }
      }
   }
   else {
      PrintMsg("I","OSF deleted for $exp from $path");
   }

   ## - remove the POD file OSF (first for complete, then duplicate OSFs)
   # - remove the POD file OSF (first for duplicate, then complete OSFs)
   $whacked_pod = $pod . "_" . $exp;
   # don't report anything for duplicate OSFs, since they are rare if they exist
   PrintMsg ("D", "Quiet attempt to delete duplicate pod OSF:");
   PrintMsg ("I", "osf_delete -p $path -f $whacked_pod'*' -t dup ");
   `osf_delete -p $path -f $whacked_pod'*' -t dup`;

   PrintMsg ("D", "Noisier attempt to delete expected pod OSF:");
   PrintMsg ("I", "osf_delete -p $path -f $whacked_pod'*' -t pod -c DP -s c ");
   `osf_delete -p $path -f $whacked_pod'*' -t pod -c DP -s c`;
   if ($? != 0) {
      PrintMsg("W","WARNING: Failed to delete pod OSF for $pod from $path");
   }
   else {
      PrintMsg("I","pod OSF deleted for $pod from $path");
   }
 }
 close(PODLIST);

 # now remove any product files from the data reduction directories
 # (use the first 8 chars of the product name + a wildcard to catch
 #  the primary and any sub products)
 #
 $product = substr($p_dset,0,8);

 PrintMsg("I","Remove, if any, product files from data reduction dirs");
 @files = glob($caldir . $product. "*");
 #PrintMsg("I","if scalar \@files, do caldir product stuff.  \@files is @files.");
 if (scalar(@files)) {
   PrintMsg("I","unlinking caldir products: @files");
   my $ok = unlink @files;
   PrintMsg ("I","caldir products: $ok files removed ");
   if ( ! $ok ) {
     PrintMsg ("W","WARNING Failure unlinking cal products from $caldir ");
   }
 } 
 else {
   PrintMsg ("I","INFO: No cal products to unlink from $caldir ");  
 }

 @files = glob($sisdir . $product. "*");
 #PrintMsg("I","if scalar \@files, do sisdir product stuff.  \@files is @files.");
 if (scalar(@files)) {
   PrintMsg("I","unlinking sis products: @files");
   PrintMsg ("I","sisdir products: $ok files removed ");
   my $ok = unlink @files;
   if ( ! $ok ) {
     PrintMsg ("W","WARNING Failure unlinking sis products from $sisdir ");
   }
 }
 else {
   PrintMsg ("I","INFO: No sis products to unlink from $sisdir ");  
 }

 # remove the product OSF from the data reduction BB
 PrintMsg ("I","Remove the product OSF from the data reduction BB");
 PrintMsg ("I","osf_delete -p $path -f $product'*' ");
 `osf_delete -p $path -f $product'*'`;
 if ($? != 0) {
   PrintMsg("W","WARNING: Failed to delete product OSF for $product from $path");
 }
 else {
   PrintMsg("I","product OSF deleted for $product from $path");
 }

 # remove any related-ASN OSFs from the data reduction BB and the
 # reservation OSFs as listed in the .rsvlist file
 #
 PrintMsg ("I","remove any related-ASN OSFs from the data reduction BB, according to *.rsvlist ");
 $infile = $p_dir . ".rsvlist";
 if (!open(RSVLIST, "$infile")) {
    # a missing .rsvlist is OK, it will happen under certain
    # flushing scenarios
    PrintMsg("W","failed to open infile (rsvlist) $infile"); 
 }
 else {
   while (<RSVLIST>) {
    #
    # save the read buffer ($_), remove the newline
    $exp = $_;
    chomp($exp);
    #
    # clean data reduction pipeline first
    # - remove cal files for this exposure
    @files = glob($caldir . $exp . "*");
    if (scalar(@files)) {
       PrintMsg("I","unlinking ASN-related cal files: @files");
       my $ok = unlink @files;
       PrintMsg ("I","ASN-related caldir: $ok files removed ");
       if ( ! $ok ) {
         PrintMsg ("W","WARNING Failure unlinking ASN-related cal files from $caldir ");
       }
    }
    else {
       PrintMsg("I","No ASN-related cal files to unlink in $caldir");
    }

    # - remove sis files for this exposure
    @files = glob($sisdir . $exp . "*");
    if (scalar(@files)) {
       PrintMsg("I","unlinking ASN-related sis files: @files");
       my $ok = unlink @files;
       PrintMsg ("I","ASN-related sisdir: $ok files removed ");
       if ( ! $ok ) {
         PrintMsg ("W","WARNING Failure unlinking ASN-related sis files from $sisdir ");
       }
    }
    else {
       PrintMsg("I","No ASN-related sis files to unlink in $sisdir");
    }

    #
    # first try the data reduction BB (may not be anything there, so errors are OK)
    PrintMsg ("I","first try the data reduction BB (may not be anything there, so errors are OK)");
    PrintMsg ("I","osf_delete -p $path -f $exp'*' ");
    `osf_delete -p $path -f $exp'*'`;
    if ($? == 0) {
       PrintMsg("I","deleted data reduction BB OSF from $path for $exp");
    }
    #
    # now the reservation BB, there should be something there
    # (no wildcard used on this BB)
    PrintMsg ("I","now the reservation BB (or did unreserve get it already?) ");
    PrintMsg ("I","osf_delete -p $reserve_path -f $exp ");
    `osf_delete -p $reserve_path -f $exp`;
    if ($? == 0) {
       PrintMsg("I","DELETED reservation OSF from $reserve_path for $exp");
    }
    else {
       PrintMsg("W","WARNING Could not delete reservation OSF from $reserve_path 
                for $exp.  (unreserved?) ");
    }
   }
   close(RSVLIST);
 }

# complete, exit success
 PrintMsg ("I","unreserve Complete, exit success");
 exit $all_is_well;
