#!/usr/bin/env perl
#----------------------------------------------------------------------------
#
# Name: asn_product_status
#
# This script is designed to be used in at the end of the calibration script
# for those instruments that generate association products. The calibration
# script must redirect log messages from this script to the trailer file. This
# script only writes to stdout. The calibration script makes the CAL directory
# the working directory so interactive testing must be done in the directory of
# the FITS association table.
#
# This perl script verifies that the input environment variables are OK, then
# gets the dataset rootname from the command line. It returns with success if 
# the UPDATE_ASN_PRODUCT_STATUS flag is FALSE or the rootname is not an association.
# 
# The process appends the standard extension for association tables to the
# rootname to get the filespec. It verifies read-access to the asn table. It
# uses the listasn tool to read the table. For every listasn product record,
# it updates the asn_member.product_status field.  After successful updating
# of the database, it checks that the FGS_PATH_NAME is not set to NONE, and
# then it checks if the FGS OSF is waiting for product status data and 
# restarts the FGS BLDASN process, if necessary.
#
# Usage:  (both within calxxx script or interactively)
#	asn_product_status.pl   association_id
#
#	Note that the following environment variables (logicals) are 
#       always required: DSQUERY, and OPUS_DB.
#
#       The pipeline ENV variable OK_TO_UPDATE_DATABASE if present is checked.
#
# History:
# Date     OPR      Who       Reason
# -------- -------- --------- ---------------------------------------------
# 05/27/01 43960    Baum      Initial version
# 04/26/02 45738    Baum      Use external subroutines.
# 10/25/02 46774    Baum      Fix bug in arguments to system call.
# 10/08/03 49496    MSwam     Change OTFR_WORLD to UPDATE_ASN_PRODUCT_STATUS
# 05/08/06 55509    Sherbert  Remove inconsistencies with path defaults
# 03/06/08 44712    Sherbert  Move from ST_DBlib to DBI interface
# 06/30/10 64432    MSwam     Use single quotes for SQLServer
# 
#----------------------------------------------------------------------------

# set up external routines
unshift @INC,(split /:/, $ENV{PATH});
require 'printmsg.pl';       # prints a formatted status message
require 'do_dbi_pkg.pl';     # run query returning only record count
#----------------------------------------------------------------------------
#specify exit status values
#---------------------------------------------------------------------

    $PROCESS_FAILURE = 1; # exit status for CAL script
    $PROCESS_SUCCESS = 0; # exit status for CAL script

#---------------------------------------------------------------------
#check for calling arguments
#---------------------------------------------------------------------

    $num_arg = scalar @ARGV;

    if ($num_arg != 1) {
       PrintMsg("E","Bad usage: need one argument - association rootname.");
       exit( $PROCESS_FAILURE);
    }
    $ASN_ROOT = lc($ARGV[0]);
#---------------------------------------------------------------------
# exit successfully, if UPDATE_ASN_PRODUCT_STATUS is FALSE or 
# this is not an association
#---------------------------------------------------------------------
    $update_asn_product_status = $ENV{"UPDATE_ASN_PRODUCT_STATUS"};
    if (defined($update_asn_product_status) && $update_asn_product_status =~ /FALSE/) {
       exit( $PROCESS_SUCCESS);
    }
    if ("0" ne substr($ASN_ROOT,8,1)) {
       exit( $PROCESS_SUCCESS);
    }
#---------------------------------------------------------------------
# check access to database
#---------------------------------------------------------------------
    $OK_UPDATE = $ENV{"OK_TO_UPDATE_DATABASE"};
    if (!defined($OK_UPDATE)) {$OK_UPDATE = 'TRUE';}
    if ( "T" ne uc(substr($OK_UPDATE,0,1)) ) {
       PrintMsg ("W","OK_TO_UPDATE_DATABASE not TRUE.");
       PrintMsg ("W","This PATH must not be used in operations.");
       exit( $PROCESS_SUCCESS);
    }
#---------------------------------------------------------------------
# get the external variables
#---------------------------------------------------------------------
    $DSQUERY=           $ENV{"DSQUERY"};
    $OPUS_DB=           lc($ENV{"OPUS_DB"});
#---------------------------------------------------------------------
# begin processing
#---------------------------------------------------------------------
    $asn_filespec = $ASN_ROOT."_asn.fits";
    PrintMsg ("I","--- start --- Association Product Status Updater -------");
    PrintMsg ("I","--- ASN: $asn_filespec");
#---------------------------------------------------------------------
# check pipeline variables
#---------------------------------------------------------------------
    $fgs_path_name      = $ENV{"FGS_PATH_NAME"};
    if (defined($fgs_path_name)) {
       $fgs_asn_column     = $ENV{"FGS_ASN_COLUMN"};
       $fgs_hold_status    = $ENV{"FGS_HOLD_STATUS"};
       $fgs_restart_status = $ENV{"FGS_RESTART_STATUS"};
       if (!(defined(fgs_asn_column) &&
             defined($fgs_hold_status) && defined($fgs_restart_status))){
         PrintMsg("W","FGS_ASN_COLUMN, FGS_HOLD_STATUS,".
                      "and FGS_RESTART_STATUS not all defined.");
         PrintMsg("I","FGS Pipeline cannot be restarted."); 
         $restart = 0;
       } elsif ($fgs_path_name eq "NONE") {
           $restart = 0;  # this pipeline intentionally not accessing FGS
       } else {
           $restart = 1;
       }
    } else {
       $restart = 0;
    }
#---------------------------------------------------------------------
#verify input asn table exists
#---------------------------------------------------------------------
    if (!(-e $asn_filespec)) {
       PrintMsg ("E","Cannot find association file at $asn_filespec");
       exit( $PROCESS_FAILURE);
    }
#---------------------------------------------------------------------
# open database for queries
#---------------------------------------------------------------------
    $db = DoDBIopen( $DSQUERY, $OPUS_DB, $PROCESS_FAILURE );
#---------------------------------------------------------------------
# read table using listasn program
#---------------------------------------------------------------------
    @table = `listasn $asn_filespec -s`;
    if ($?) {
       PrintMsg ("E","Error status returned from asnlist for $asn_filespec.");
       exit( $PROCESS_FAILURE);       
    }
    $lines = scalar @table;
    if ($lines == 0) {
       PrintMsg ("E","No output lines from asnlist tool.");
       exit( $PROCESS_FAILURE);
    }
#---------------------------------------------------------------------
# check each line in the table for product records
#---------------------------------------------------------------------
    $asn_id = uc($ASN_ROOT);
    $num_products=0;
    for (@table) {
      chomp;   # remove newline
      $line = $_;
      #------------------------------------------------------------------
      # extract $inst from first character of line, $program from next
      # three characters, $obset_id from next two characters, $member_num
      # from next three characters, and after PROD<any-non-white><space>,
      # extract $present from either the value T or F.
      #------------------------------------------------------------------
      ($inst,$program_id,$obset_id,$member_num,$present) = 
        ($line=~/^(.)(...)(..)(...)\sPROD\S+\s([TF])$/);

      if (defined($present)) {
         if ($present eq "T") {
            $code = "C";
         }else{
            $code = "N";
         }
         $prod_member = $inst.$program_id.$obset_id.$member_num;

#---------------------------------------------------------------------
# update asn_members.product_status 
#---------------------------------------------------------------------

$query = <<"EOQ";
UPDATE asn_members SET product_status='$code'
WHERE association_id='$asn_id' and program_id='$program_id' and
      obset_id='$obset_id' and member_num='$member_num'
EOQ

         $count = DoDBI( $db, $query );
         if ($count != 1) {
           PrintMsg ("E","Cannot update asn_members for $prod_member");
           exit( $PROCESS_FAILURE);
         }
         $num_products+=1;
         PrintMsg ("I","The product_status for $prod_member is $code.");
      }
    }
    if ($num_products == 0) {
      PrintMsg ("E",
        "Did not find any products in the following listasn output");
      for (@table) {
        $line = $_;
        print "$line\n";
      }
      PrintMsg ("E", "No asn_members updated.");
      exit( $PROCESS_FAILURE);
    }
#---------------------------------------------------------------------
# end of all queries
#---------------------------------------------------------------------
    DoDBIclose( $db );
#---------------------------------------------------------------------
# restart holding FGS OSF if pipeline mode variable defined 
#---------------------------------------------------------------------
    if ($restart){
      $osf_stat=`osf_test -p $fgs_path_name -f $ASN_ROOT -pr $fgs_asn_column`;
      if ($?) {
       PrintMsg ("I","osf_test error for $ASN_ROOT in path: $fgs_path_name.");
      } else {
        $osf_stat= substr( $osf_stat, 0, 1);
        if ($fgs_hold_status eq $osf_stat) {
          if ($sys_stat = system("osf_update","-p",$fgs_path_name,
            "-f",$ASN_ROOT,"-c",$fgs_asn_column,"-s",$fgs_restart_status)) {
              $return_stat = $sys_stat/256;
            PrintMsg ("E", 
              "Failed to update OSF for $ASN_ROOT. Status $return_stat");
            exit( $PROCESS_FAILURE);
          } else {
            PrintMsg ("I", 
             "Successful update of FGS OSF $ASN_ROOT, column $fgs_asn_column.");
          }
	} elsif (length($osf_stat) == 1){
          PrintMsg ("I",
	    "FGS OSF $ASN_ROOT in path: $fgs_path_name, ".
	    "$fgs_asn_column has status $osf_stat.");
        } else {	  
          PrintMsg ("I",
	    "FGS OSF $ASN_ROOT not found in path: $fgs_path_name.");
	}
      }
    }
#---------------------------------------------------------------------
# signoff for successful processing
#---------------------------------------------------------------------
    PrintMsg ("I","---  end  --- Association Product Status Updater -------");
    exit( $PROCESS_SUCCESS);
