#!/usr/bin/env perl
########################################################################
#
#  Name: ana5sfc
#
#  Purpose:  This script runs the ana5sfc.x program, which calculates
#            analysis surface parameters.
#
#  Required Command-line Parameters:
#     nymd .... Year-month-day, e.g., 19990901
#     nhms .... Hour-minutes-seconds, e.g., 123000
#     expID ... Experiment ID, e.g. b3p7_c1
#     ldir .... local directory where data does (or will) reside
#
#  Required Flag
#
#  Optional Flags
#     -clean ... clean output
#     -help .... show script usage information
#     -hour .... process single hour only (default case)
#     -mean .... calculate monthly mean only
#     -month ... process every hour in month + calculate monthly mean
#     -rdir machine:dirname ... remote machine/directory where data can
#                               be found
#  Notes:
#  1. Only one of the following options can be selected:  -help, -month,
#     -mean, and -hour. If more than one is listed, then they will have the
#     precedence shown in the previous sentence.
#  2. If none of the four options above are given, the default case will
#     be -hour.
#  3. The -clean and -rdir flags can be used with other options.
#  4. The the value for the -rdir flag, if used, must contain both a machine
#     name and a directory name, separated by a comma.
#  5. If an -rdir value is specified, the script will perform a
#     demigration on the remote machine, and then copy the files to the
#     ldir directory.
#  6. If no -rdir value is provided, the data is presumed to already be
#     in the ldir data directory.
#
#  !REVISION HISTORY:
#
#   16Sep2005  Stassi   Initial version of code.
#   17Apr2018  Todling  Invoke proper sfc grid (default g5).
#
########################################################################

use Env;                  # make env vars readily available
use FindBin;              # so we can find where this script resides
use File::Basename;       # for basename(), dirname()
use File::Copy "cp";      # for cp()
use Getopt::Long;         # command line options

#-----------------------#
# variable declarations #
#-----------------------#
my ( $ana5sfcX, $GFIO_meanX );
my ( $day, $startday, $endday );
my ( $hour, $time, $ctlflg, $cleanflg );
my ( $anaETA, $bkgETA, $bkgSFC, $anaSFC );
my ( $anaSFCave, $yyyymm, $expID );
my ( $ldir, $rmach, $rddir );
my ( $sfc_grid );
my @hours;
my @infiles;

#*** set debug flag
my $DEBUG = 1;

#----------------#
# initialization #
#----------------#
init();

#-----------------#
# process hour(s) #
#-----------------#

#*** run program from nobackup directory
chdir $ldir or die "Cannot chdir to $ldir";

if ( $ctlflg ne "mean" ) {       #*** either -hour or -month ****

    $day = $startday - 1;
    while ($day < $endday) {
        $day++;
        if ($day < 10) {$day = "0" . ($day + 0)};

        foreach $hour (@hours) {
            if ($DEBUG) {sleep 1};
            if ($hour < 10) {$hour = "0" . ($hour + 0)};
            $time = $yyyymm . $day . "_" . $hour . "z";

            $anaETA = $expID . ".ana.eta." . $time . ".nc4";
            $bkgETA = $expID . ".bkg.eta." . $time . ".nc4";
            $bkgSFC = $expID . ".bkg.sfc." . $time . ".nc4";
            $anaSFC = $expID . ".ana5.sfc." . $time . ".nc4";

            #*** clean output and then proceed to "next" ***
            #===============================================
            if ($cleanflg) {
                print "output file, $anaSFC";
                if ( -e $anaSFC ) {
                    unlink $anaSFC;
                    print " -> unlinked\n";
                } else {
                    print " -> does not yet exist.\n";
                }
                next;
            }

            if ($hour % 6 == 0) {

                #*** 6-hourly synoptic hours ***
                #===============================
                if ($rmach) {
                    print "ssh $rmach dmget $rddir/{$anaETA,$bkgETA,$bkgSFC}\n";
                    system "ssh $rmach dmget $rddir/{$anaETA,$bkgETA,$bkgSFC}";

                    print "scp $rmach:$rddir/{$anaETA,$bkgETA,$bkgSFC} .\n";
                    system "scp $rmach:$rddir/{$anaETA,$bkgETA,$bkgSFC} \.";
                }

                print "$ana5sfcX $sfc_grid $anaETA $bkgETA $bkgSFC -o $anaSFC\n";
                system "$ana5sfcX $sfc_grid $anaETA $bkgETA $bkgSFC -o $anaSFC";
                print "  output -> $anaSFC\n";

            } else {

                #*** non-synoptic hours
                #======================
                if ($rmach) {
                    print "ssh $rmach dmget $rddir/{$bkgETA,$bkgSFC}\n";
                    system "ssh $rmach dmget $rddir/{$bkgETA,$bkgSFC}";

                    print "scp $rmach:$rddir/{$bkgETA,$bkgSFC} .\n";
                    system "scp $rmach:$rddir/{$bkgETA,$bkgSFC} \.";
                }

                print "$ana5sfcX $sfc_grid $bkgETA $bkgETA $bkgSFC -o $anaSFC\n";
                system "$ana5sfcX $sfc_grid $bkgETA $bkgETA $bkgSFC -o $anaSFC";
                print "  output -> $anaSFC\n";
            }
        }
    }
}


#-----------------------------#
# generate monthly means file #
#-----------------------------#

if ( $ctlflg ne "hour" ) {       #*** either -mean or -month ****

    #*** NOTE: output gets clean automatically, even without -clean option ***
    $anaSFCave = $expID . ".ana5.sfc." . $yyyymm . ".ave.nc4";
    print "monthly output file, $anaSFCave";
    if (-e $anaSFCave) {
        unlink $anaSFCave;
        print " -> unlinked.\n";
    } else {
        print " -> does not yet exist.\n";
    }


    #*** create new output ONLY IF -clean flag has not been selected ***
    if (! $cleanflg) {
        @infiles = glob "${expID}.ana5.sfc.${yyyymm}*z.nc4";
        system "$GFIO_meanX -o $anaSFCave @infiles";
        print "  output -> $anaSFCave\n";
    }
}


#ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
#ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
sub init {

    my ( $lastday, $lastDayOfMonth );
    my ( $nymd, $nhms );
    my ( $yyyy, $mm, $dd );
    my ( $min, $secs );
    my ( $ly1, $ly2, $ly3 );

    GetOptions( "clean", "help", "hour", "mean", "month", "rdir=s" );
    usage() if (@ARGV != 4);

    $ctlflg = "hour";
    $cleanflg = 0;
    if ($opt_mean)  {$ctlflg = "mean"};
    if ($opt_month) {$ctlflg = "month"};
    if ($opt_clean) {$cleanflg = 1};

    $sfc_grid = "-g5";
    if ($opt_merra) {$sfc_grid = ""};

    #---------------------------------#
    # extract data directory location #
    #---------------------------------#
    if ($opt_rdir) {
        if ($opt_rdir =~ /:/) {
            ($rmach, $rddir) = ( $opt_rdir =~ /(.*):(.*)/ );
        } else {
            usage();
        }
    }

    #--------------------------#
    # extract date/time values #
    #--------------------------#
    ($nymd, $nhms, $expID, $ldir) = @ARGV;
    ($yyyy, $mm, $dd) = ($nymd =~ /(....)(..)(..)/);
    ($hour, $min, $secs) = ($nhms =~ /(..)(..)(..)/);
    ($yyyymm) = ($nymd =~ /(......)../);

    #-----------------------------#
    # calculate last day of month #
    #-----------------------------#
    @lastDayOfMonth = (31,28,31,30,31,30,31,31,30,31,30,31);
    $lastday = $lastDayOfMonth[$mm-1];
    if ($mm == 2) {
        $ly1 = int ($yyyy / 4) * 4;
        $ly2 = int ($yyyy / 100) * 100;
        $ly3 = int ($yyyy / 400) * 400;

        if ((($yyyy == $ly1) && ($yyyy != $ly2)) || ($yyyy == $ly3)) {
            $lastday  = 29;
        }
    }

    #---------------------------------#
    # initialize local data directory #
    #---------------------------------#
    if ( ! -d $ldir) {
        if (system "mkdir -p $ldir") {
            die "Cannot mkdir $ldir";
        }
    }

    #------------------------------------------------------#
    # initialize variables for startday, endday, and hours #
    #------------------------------------------------------#
    $startday = $dd;
    $endday = $dd;
    @hours = ( $hour );

    if ( $ctlflg eq "month" ) {
        $startday = 1;
        $endday = $lastday;
        @hours = (0,3,6,9,12,15,18,21);
    }

    #----------------------------------------------#
    # initialize variables for executable programs #
    #----------------------------------------------#
    $fvroot = dirname($FindBin::RealBin);
    $ana5sfcX = $fvroot . "/bin/ana5sfc.x";
    $GFIO_meanX = $fvroot . "/bin/GFIO_mean_r4.x";
}


#ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
#ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
sub usage {

#---------------------------------
    print << "EOF";

Usage: $0 [OPTION] nymd nhms expID ldir

  required command-line parameters:
       nymd .... year-month-day (yyyymmdd)"
       nhms .... hour-min-secs  (hhmmss)"
       expID ... Experiment ID, e.g. b3p7_c1"
       ldir .... local directory where data does (or will) reside

  OPTIONS
       -clean ... remove output (can be used with another option]
       -help .... show this help message
       -hour .... process single hour only (DEFAULT CASE)"
       -mean .... generate monthly means file only"
       -month ... process entire month and generate monthly means file"
       -rdir machine:dirname .... remote machine/directory where data can be found

EOF
#---------------------------------
exit (1)

}
