#!/usr/bin/env perl
#----------------------------------------------------------------------------
#
# Name: eng_finish.pl
#
# This perl script is used for three pipeline processes. The resource file or
# class name specifies the database records that it uses to control the
# pipeline. Interactive mode is used only during testing as it cannot update
# OSFs.
#
# Interactive Usage:
#	>eng_finish.pl <product_rootname> -t <data_id>
#
#       where product_rootname is gyyyydddhhmmss for GSA class or
#       ipppssoot for FGS and AST class. In interactive mode the
#       product_status is updated and tested, and the test results
#       are logged but no OSFs are updated.
#
# Pipeline Usage:
#       command:eng_finish.pl 
#     
#       In the pipeline the resource file must set the following ENV 
#       variables: OSF_DATASET, OSF_DATA_ID, ENG_DATA_ID, ENG_STEP, 
#       ENG_COMPLETE, and TELEM_PATH.
#
#	Note that the following environment variables (logicals) are 
#       always required in both modes: OPUS_SERVER and OPUS_DB.
#
#
# History:
# Date     OPR      Who         Reason
# -------- -------- ----------  ---------------------------------------------
# 06/26/01 43966    Baum        Initial code
# 04/29/02 45738    Baum        Use external subroutines.
# 07/30/02 46276    Baum        Check eng file for case and fail on missing OSF
# 08/11/05 53803    MSwam       Replace PATH_FILE_NAME with PATH_BASENAME
# 03/24/10 64274    MSwam       Replace ST_DBlib with DBI
# 06/30/10 64432    MSwam       Use single quotes for SQLServer
# 09/18/12 72255    Sherbert    get rid of DSQUERY
#----------------------------------------------------------------------------
# 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

    $OSF_SUCCESS =      1;   # exit status for XPOLL
    $OSF_FAILURE =      2;   # exit status for XPOLL

#check for arguments

    $num_arg = scalar @ARGV;

    if ($num_arg > 0 && substr($ARGV[0],0,1) ne "-") {
      $interactive = 1;
    } else {
      $interactive = 0;
    }
    if ($interactive) {
      $fail_msg = 
        "Usage example: >eng_finish.pl o8ha35b2j -t fgs\nTry again.\n"; 
      if ($num_arg != 3) {
        print $fail_msg;
        exit( $OSF_FAILURE);
      }
      # Verify arguments
      $data_id = lc($ARGV[2]);
      if ($data_id ne "fgs" &&
          $data_id ne "gsa" &&
          $data_id ne "ast") {
        print "Third argument must be fgs, gsa or ast\n";
        exit( $OSF_FAILURE);
      }
      $prod_root = $ARGV[0];
      # Verify gyyyydddhhmmss format for FGS or AST rootnames
      if (($data_id eq "gsa") && !($prod_root=~/^g\d\d\d\d\d\d\d\d\d\d\d\d\d$/)){
        print $fail_msg;
        exit( $OSF_FAILURE);
      }
      # Verify IPPPSSOOT format for FGS or AST rootnames
      if (($data_id ne "gsa") && !($prod_root=~/^\D\w\w\w\w\w\w\w\D$/)){
        print $fail_msg;
        exit( $OSF_FAILURE);
      }
      if ($ARGV[1] ne "-t") {
        print $fail_msg;
        exit( $OSF_FAILURE);
      }
      $eng_data_id = "eng";  # hardcoded for testing
    } else {
      # Verify ENV variables
      $prod_root = $ENV{"OSF_DATASET"};
      $path    = $ENV{"PATH_BASENAME"};
      $data_id = lc($ENV{"OSF_DATA_ID"});
      $eng_data_id = lc($ENV{"ENG_DATA_ID"});  
      $eng_step = $ENV{"ENG_STEP"};
      $eng_complete = $ENV{"ENG_COMPLETE"};
      $telem_path = $ENV{"TELEM_PATH"};
      
      if (!defined($prod_root) || !defined($eng_data_id) || 
          !defined($eng_step) || !defined($eng_complete) || 
	  !defined($telem_path)) 
      {
        PrintMsg("E","Missing ENV variable in resource file. Need:");
        PrintMsg("E","ENG_DATA_ID, ENG_STEP, ENG_COMPLETE, and TELEM_PATH");
        exit( $OSF_FAILURE);
      }
      # cleanup path name
      $colon   = rindex($path,":");
      $path    = substr($path,$colon+1);
    }
    $OPUS_SERVER = $ENV{"OPUS_SERVER"};
    $OPUS_DB = lc($ENV{"OPUS_DB"});
    $uc_root = uc($prod_root);
    $class = uc($data_id);

# begin processing

    PrintMsg ("I","--- start --- Finish up $prod_root $class data -------");
#---------------------------------------------------------------------
# open database for queries
#---------------------------------------------------------------------
    $db = DoDBIopen( $OPUS_SERVER, $OPUS_DB, $OSF_FAILURE);

#---------------------------------------------------------------------
# update complete_flag in product_status
#---------------------------------------------------------------------
    $query = <<"EOQ";
UPDATE product_status
SET complete_flag = 'Y'
WHERE product_rootname='$uc_root' and product_type='$class'
EOQ

    $count = DoDBI( $db, $query);

    if ($count == 0) {
      PrintMsg("E","Cannot find product_status record for $uc_root $class.");
      exit( $OSF_FAILURE);
    }
#---------------------------------------------------------------------
#  Use product_eng_map (twice) and product_status to find all eng_rootnames,
#  and the minimum complete_flag in product_status for all
#  eng files used by $product_rootname
#---------------------------------------------------------------------

$query = <<"EOQ";
SELECT m.eng_rootname, MIN(s.complete_flag)
FROM product_eng_map m, product_status s, product_eng_map m2
WHERE m.product_rootname='$uc_root' and
  m.product_type='$class' and
  m2.product_type = m.product_type and
  m2.eng_rootname = m.eng_rootname and
  s.product_rootname = m2.product_rootname and
  s.product_type = m2.product_type
GROUP BY m.eng_rootname
EOQ
    $update_failure = 0; 
    $err_msg = "Cannot query first eng_rootname.";
    $err_msg2 = "Cannot query next eng_rootname.";

    $sth = DoDBIexecute( $db, $query);
    while ( ($eng_rootname,$min_complete) = DoDBIfetch( $db, $query, $sth) ) {
      PrintMsg("I","Checking if $eng_rootname is still required for other ".
        "$class products.");      
      if ($min_complete eq "N") {
        # there is at least one complete_flag=N value for this eng file
        PrintMsg("I","$eng_rootname is still required for $class data.");
      } else {
        # all eng_ready values must be Y
        PrintMsg("I","$eng_rootname is not longer required for $class.");
        if (!$interactive) {ProcessEng($eng_rootname);}
      }
    }
#---------------------------------------------------------------------
# end of all queries
#---------------------------------------------------------------------
    DoDBIclose($db);

    $status = $OSF_SUCCESS;
    if ($update_failure) {
       PrintMsg("E","At least one missing eng OSF detected.");
       PrintMsg("I","Telemetry files above must be deleted manually.");
       $status = $OSF_FAILURE;
    } 
    PrintMsg ("I","---  end  --- Finish up $prod_root $class data -------");
    exit( $status);  

#---------------------------------------------------------------------
# end of main procedure -- subroutines follow
#---------------------------------------------------------------------
sub ProcessEng
{
    my ($eng_root) = @_;
    my $cmd;
    my $dcf_num;

    # check file presence and case of rootname
    my $file_mask = $telem_path.$eng_root.".*";
    my @file_list = glob($file_mask);
    if ((scalar @file_list) == 0) {
       $eng_root = lc($eng_root);
       $file_mask = $telem_path.$eng_root.".*";
       @file_list = glob($file_mask);
       if ((scalar @file_list) == 0) {
          PrintMsg("W","Missing $file_mask - nothing to delete.");
	  return;
       }
    }    
    $cmd = "osf_test -p $path -f $eng_root -t $eng_data_id -pr dcf_num";
    $dcf_num = `$cmd`;            # backticks invoke child process
    if ($?) {                     # tests child process status where 0 is OK
        PrintMsg("I",$cmd);
	PrintMsg("E", "osf_test failed for $eng_root \n");
	exit ($OSF_FAILURE);
    }
    if (dcf_num eq "") {
      PrintMsg("W", "Cannot find OSF for $eng_root \n");
      $update_failure = 1;
    } else {
      # update OSF for eng_file using ENG_STEP and ENG_COMPLETE
      $cmd = "osf_update -p $path -f $eng_root -t $eng_data_id ".
             "-c \"$eng_step\" -s $eng_complete";
      `$cmd`;
      if ($?) {
        PrintMsg("I",$cmd);
	PrintMsg("E", "osf_update failed for $eng_root data_id $eng_data_id\n");
        $update_failure = 1;
      } 
    }
}
