#!/usr/bin/env perl
#----------------------------------------------------------------------------
#
# Name: update_otfr_spec_proc.pl
#
# This perl script fills a database record in the "otfr_special_processing"
# relation of the ARCH_SERVER::ARCH_DB database using an 8-character 
# IPPPSSOO name from the command line, or a user prompt. 
# This script replaces both merge_reqd.pl or edt_reqd.pl, since much of the
# code in each was the same.  It can be called by either of two csh scripts
# to help keep the user interface similar to way it was: merge_reqd.csh or
# edt_reqd.csh
#
# This script performs the insert of the database record, loading:
#
#   osp_instrument       - depends on first character of IPPPSSOO provided
#   osp_data_set_name    - the 8 character string provided
#   osp_data_source      - empty when MERGE req'd   OR
#                          EDT when EDT req'd
#   osp_processing_steps - set to "MERGE_REQD" when MERGE req'd   OR
#                          empty when EDT req'd
#   osp_pr_number        - empty
#   osp_user_name        - obtained from env variable USER
#   osp_entry_date       - today's date
#   osp_status           - set to "ACTIVE"
#   osp_status_date      - today's date
#
# Adding this record to the database will cause this dataset to be
# processed from its EDT set in any future OTFR requests or alert OTFR to
# the fact that a merge is required for a Q/S or S/Q-split observation.
#
# Usage:
#	% update_otfr_spec_proc.pl [edt|merge] [ipppssoo]
#
#       If the argument is not provided on the command-line, it will be
#       prompted for.
#
#	Note that the following environment variables (logicals) are required:
#       ARCH_SERVER - points to the DADS db server
#       ARCH_DB     - points to the DADS database
#
# History:
# Date     OPR    Who         Reason
# -------- ------ ----------  ---------------------------------------------
# 06/09/05 53606  Sherbert    first merged version
# 02/01/06 53606  Sherbert    Create subroutines?
# 08/28/06 53606  Sherbert    UPDATE should include an osp_user_name, too
# 08/29/06 53606  Sherbert    Improve usage statement
# 09/06/06 53606  Sherbert    Code Rvw: UNKNOWN instrument should be error
# 03/24/10 64274  MSwam       Use DBI instead of ST_DBlib
#
#----------------------------------------------------------------------------

 ## adjust the Perl include dir using PATH
 my $PATH=      $ENV{"PATH"};
 @parts = split /:/, $PATH;
 while (defined($val = pop(@parts))) {
   if (substr($val,0,1) eq "/") { unshift(@INC, $val)}
 }

 ## get the external variables
 my $ARCH_SERVER = $ENV{"ARCH_SERVER"};
 my $ARCH_DB     = lc($ENV{"ARCH_DB"});
 my $uname       = $ENV{"USER"};
 
 require 'printmsg.pl';	# PrintMsg routine
 require 'do_dbi_pkg.pl'; # database access

 $SUCCESS = 0;
 $FAILURE = 1;
 my ($type, $inname, $query, $exit_status);


 ##
 ## verify 2 arguments are present 
 ## (#argv=0 when there is exactly one argument)
 ##
#if ($#ARGV != 1) {     ## Technically correct
 if ($#ARGV != 1 && 2 != $#ARGV ) {     ## Allows automated testing
    PrintMsg ("E","Incorrect number of arguments");
    PrintUsage();
 }
 else {
    $type   = lc($ARGV[0]);
    $inname = $ARGV[1];
 }
 if ( 2 == $#ARGV ) { $Atest = 1 }    ## yes, I want it global
 else { $Atest = 0 }
 PrintMsg ("D","input type is $type and input name is $inname; Atest is $Atest");

 ## Verify input type
 if ( $type !~ /edt/ && $type !~ /merge/ ) {
    PrintMsg ("E", "Incorrect input type ($type).  Please use 'edt' or 'merge'.");
    exit ( $FAILURE );
 }

 ## Clean up and verify input name is as user expected
 ## subroutine will exit program if there are problems
 my $ipppssoo = cleanInputName($inname);
 
 ## assign instrument
 my $instrume;
 if    ($ipppssoo =~ /^O/) { $instrume = "STIS";   }
 elsif ($ipppssoo =~ /^U/) { $instrume = "WFPC2";  }
 elsif ($ipppssoo =~ /^N/) { $instrume = "NICMOS"; }
 elsif ($ipppssoo =~ /^J/) { $instrume = "ACS";    }
 elsif ($ipppssoo =~ /^I/) { $instrume = "WFC3";   }
 elsif ($ipppssoo =~ /^L/) { $instrume = "COS";    }
 elsif ($ipppssoo =~ /^X/) { $instrume = "FOC";    }
 else { 
    PrintMsg ("E", "UNKNOWN instrument, judging by first character of ipppssoot. ");
    exit ( $FAILURE );
 }


 ## Set values of osp_data_source and osp_processing_steps
 ## according to input type
 my ($osp_data_source, $osp_processing_steps);
 if ( $type =~ /edt/ ) {
    $osp_data_source       = "EDT";
    $osp_processing_steps  = " ";
    $updateLines = "SET osp_data_source = '$osp_data_source', osp_user_name = '$uname'"
 }
 else {
    $osp_data_source       = " ";
    $osp_processing_steps  = "MERGE_REQD";
    $updateLines = "SET osp_processing_steps = '$osp_processing_steps', osp_user_name = '$uname'"
 }
 PrintMsg ("D","osp_data_source is $osp_data_source; osp_processing_steps is $osp_processing_steps");

 ## get current timestamp
 use POSIX qw(strftime);     
 my $today = strftime "%d-%b-%Y %T", localtime; 
 PrintMsg ("D","Username is $uname.");

 ## initialize database
 $db = DoDBIopen( $ARCH_SERVER, $ARCH_DB, $FAILURE);

 ## determine if a record already exists in otfr_special_processing for ipppssoo
 ## This result determines query to be done
 my $recordCount = update_or_insert($ipppssoo);
 if ( $recordCount ) {
    ## set Query to perform UPDATE

    $query = <<"EOQ";
UPDATE otfr_special_processing 
$updateLines
WHERE osp_data_set_name = '$ipppssoo'
EOQ

 } else {
    ## set Query to perform INSERT

    $query = <<"EOQ";
INSERT INTO otfr_special_processing
          ( osp_data_set_name,
            osp_data_source,
            osp_processing_steps,
            osp_pr_number,
            osp_instrument,
            osp_user_name,
            osp_entry_date,
            osp_status,
            osp_status_date )
VALUES
          ( '$ipppssoo',
            '$osp_data_source',
            '$osp_processing_steps',
            0,
            '$instrume',
            '$uname',
            '$today',
            'ACTIVE',
            '$today' )
EOQ
 }

 PrintMsg ("I","Query is \n\n$query");
 $count = DoDBI( $db, $query );
 if (1 == $count && 0 == $recordCount ) 
 {  ## insert performed
    PrintMsg("I","inserted $count record(s) into otfr_special_processing");
    print STDOUT "\nPlease file a new ARCH OPR or comment 43319 to list " .
                 "this dataset and the repair.\n\n";
    &closeDB ( $SUCCESS );
 }
 elsif (0 == $count && 0 == $recordCount ) 
 {  ## insert failed
    PrintMsg("E","inserted $count records into otfr_special_processing\n");
    &closeDB( $FAILURE ); 
 }
 elsif (1 == $count && 1 == $recordCount ) 
 {   ## update performed
     PrintMsg("I","$count record updated in otfr_special_processing."); 
     &closeDB($SUCCESS); 
 }   
 else 
 {  ## update failed
     PrintMsg("E","UPDATE FAILED for otfr_special_processing."); ## update
     &closeDB( $FAILURE ); 
 }   

 ## Should never get here because
 ## closeDB exits program
 exit;

 ##=============================================================================
 ##
 ## Clean up input name
 ##
 ## Input:  rootname from command line
 ## Output: approved IPPPSSOO ready for database
 ##
 ##   No database connection has been made yet, so no need to call closeDB
 ##   if there is a failure.
 ##
 ##=============================================================================
 sub cleanInputName 
 {
    my $inname = $_[0];
    my $ipppssoo = "UNCLEANED_ROOTNAME";

    ## Remove unacceptable characters from input rootname
    $inname =~ s/\s+//g;      ## Remove any spaces in input
    $inname =~ s/[\W_]+//g;   ## Remove any non-word chars && _ 

    ## if input rootname is less than 8 chars, error out
    if (length($inname) < 8) {
       PrintMsg ("F","Input name ($inname) is less than 8 characters long. ");
       exit ($FAILURE);
    }

    ## if input rootname is more than 8 chars, truncate at 8
    if (length($inname) > 8) {
       $ipppssoo = substr($inname, 0, 8);
       PrintMsg ("W","Truncating dataset name to 8 chars: $ipppssoo ");
    }
    else {
       $ipppssoo = $inname;
    }
    ## uppercase it
    $ipppssoo = uc($ipppssoo);

    ## IF this is NOT a test (3rd param on command line)
    ## Ask for verification that this is the intended IPPPSSO
    if ( ! $Atest ) {
        print "\nAbout to create a db entry for IPPPSSOO $ipppssoo. \n";
        print "Is this your intended IPPPSSOO? [y|n]\n";
        my $answer = <STDIN>;
        chomp($answer);
        # $ipppssoo is NOT the intended IPPPSSOO, therefore exit
        if ( $answer !~ /^[Yy]/ ) {
            PrintMsg ("F","Please correct input and run script again.");
            exit ($FAILURE);
        }
    }

    return ($ipppssoo);

 }


 ##=============================================================================
 ##
 ## update_or_insert
 ##
 ## Input:
 ##         $ipppssoo
 ##
 ## Output:
 ##         $recordCount:
 ##               0 means 'use insert'
 ##               1 means 'use update'
 ##
 ## Do a test: what happens if there is a problem getting count?
 ## How is error handled?
 ##
 ##=============================================================================
 sub update_or_insert
 {

    my $ipppssoo = $_[0];

    ## first see if the record is already there (requires update, not insert)
    my $query = <<"EOQ";
SELECT COUNT(*) from otfr_special_processing
WHERE osp_data_set_name = '$ipppssoo'
EOQ

    PrintMsg ("D","$query\n");
    my @count = DoDBIselect( $db, $query );
    if ($count[0] > 0) {
        PrintMsg("I","$count[0] record(s) already in otfr_special_processing.  Using update.");
        $recordCount = 1;
    }
    else {
        PrintMsg("I","$count[0] records in otfr_special_processing.  Using insert.\n");
        $recordCount = 0;
    }

    return ($recordCount);
 }


 ##=============================================================================
 ##
 ## closeDB
 ##     Be certain to close database connection, especially if there is an 
 ##     error.
 ##
 ## Input:  $exit_status
 ## Output: none, program exits
 ##
 ##=============================================================================
 sub closeDB {

    my $exit_status = $_[0];

    DoDBIclose($db);
    exit( $exit_status );

 }

 ##=============================================================================
 ##
 ## Print Usage
 ##
 ##
 ##
 ##=============================================================================
 sub PrintUsage 
 {
    use File::Basename;
    my ($name, $unixpath, $ext) = fileparse($0, '.pl' );
    $name = $name . '.pl';

    print STDERR<<EOF; 
USAGE: $name <edt|merge> <ipppssoo> [test]
where: <edt|merge> (required) allows user to indicate if ipppssoo should be 
                   processed from EDT set OR ipppssoo requires a merge to 
                   process through pipeline (eg. Q/S-split or S/Q-split, etc.)
       <ipppssoo>  (required) specifies the 8-char ipppssoo that needs special 
                   treatment
       <test>      (optional) is any string as 3rd parameter to facilitate 
                   automated tests (prevents interactive confirmation of input)

Example:
       $name edt u8u5f208
       About to create a db entry for IPPPSSOO U8U5F208.
       Is this your intended IPPPSSOO? [y|n]
       y
       ...
EOF


    exit ( $FAILURE );

 }


