#!/usr/bin/env perl
#=======================================================================
#
# Add metadata to initial condition file to give more background information on it.
#
# Usage:
#
# addmetadata <compsetname> <options>
#
#  Erik Kluzek
#  May/14/2013
#  $Id: addmetadata 47169 2013-05-15 17:05:17Z erik $
#  $HeadURL;
#
#=======================================================================

use Cwd;
use strict;
#use diagnostics;
use English;
use Getopt::Long;
use IO::File;

#-----------------------------------------------------------------------------------------------
# Set the directory that contains this scripts.  If the command was issued using a 
# relative or absolute path, that path is in $ProgDir.  Otherwise assume the
# command was issued from the current working directory.

(my $ProgName = $0) =~ s!(.*)/!!;      # name of this script
my $ProgDir = $1;                      # name of directory containing this script -- may be a
                                       # relative or absolute path, or null if the script is in
                                       # the user's PATH

#-----------------------------------------------------------------------------------------------

my $default = "not-set";
my %data = ( 
              atm_forcing      => { val=>$default, match=>"[a-zA-Z0-9._-]+", optname=>"frc",       required=>0,  goesonfile=>1,
                                    desc=>"Atmosphere model forcing used (such as CRUNCEP or QIAN or CAM for coupled cases)"   },
              atm_forc_yrs     => { val=>$default, match=>"[0-9]+-*[0-9]*",  optname=>"yrs",       required=>0,  goesonfile=>1,
                                    desc=>"The year range the atmosphere model forcing was run over"                           },
              co2_year         => { val=>$default, match=>"[0-9]+-*[0-9]*",  optname=>"co2_yrs",   required=>0,  goesonfile=>1,
                                    desc=>"Year or year range that CO2 forcing was run over"                                   },
              compset          => { val=>$default, match=>"[a-zA-Z0-9_.-]+", optname=>"compset",   required=>1,  goesonfile=>1,
                                    desc=>"Compset name that was used for the case"                                            },
              ic_file          => { val=>$default, match=>".+\.nc",          optname=>"IC-file",   required=>1,  goesonfile=>0,
                                    desc=>"Input file to add meta-data to"                                                     },
              model_version    => { val=>$default, match=>"[a-zA-Z0-9._-]+", optname=>"version",   required=>0,  goesonfile=>1,
                                    desc=>"Model version that was used for the case"                                           },
              options          => { val=>$default, match=>".+",              optname=>"options",   required=>0,  goesonfile=>1,
                                    desc=>"Any other options that were set for the case (user_nl settings, env settings etc.)" },
           );

sub usage {
    die <<EOF;
SYNOPSIS
     $ProgName $data{'compset'}{'optname'} $data{'ic_file'}{'optname'} [options]      Adds metadata to an initial condition file to more fully describe it.
REQUIRED
     $data{'compset'}{'optname'}\t\tCompset name used to create the case.
     $data{'ic_file'}{'optname'}\t\tFilename to add meta-data to.
OPTIONS
     -$data{'co2_year'}{'optname'} <years>\t\tYear (or range of years) for CO2 forcing.
     -$data{'atm_forcing'}{'optname'} [or -f] <force>\tDescription of datm forcing used to create the case.
     -debug [or -d]\t\tDebug -- do a dry run with OUT changing the input NetCDF file.
     -help [or -h]\t\tGive this help message.
     -interactive [or -i]\tAsk for each item in turn.
     -$data{'options'}{'optname'} <options>\t\tOther options used for the simulation.
     -$data{'model_version'}{'optname'} [or -v] <vers>\tModel version this simulation was run with.
     -$data{'atm_forc_yrs'}{'optname'} [or -y] <years>\tYear range of datm forcing used to create the case.
EXAMPLES

      Add compset name and version to a fully coupled case initial condition file.

      $ProgName BCN clmi.BCN.1949-01-01_10x15_USGS_simyr1850_c121113.nc -v clm4_5_00

      Ask that the user be queried for each item in turn.

      $ProgName ICN clmi.ICN.1949-01-01_10x15_USGS_simyr1850_c121113.nc -i
EOF
}

# Process command-line options.

my %opts = ( 
              debug            => 0, 
              help             => 0, 
              interactive      => 0, 
              verbose          => 0,
           );

GetOptions(
         $data{'co2_year'}{'optname'}."=s"      => \$data{'co2_year'}{'val'},
    "f|".$data{'atm_forcing'}{'optname'}."=s"   => \$data{'atm_forcing'}{'val'},
    "y|".$data{'atm_forc_yrs'}{'optname'}."=s"  => \$data{'atm_forc_yrs'}{'val'},
         $data{'options'}{'optname'}."=s"       => \$data{'options'}{'val'},
    "v|".$data{'model_version'}{'optname'}."=s" => \$data{'model_version'}{'val'},
    "d|debug"                                   => \$opts{'debug'},
    "h|help"                                    => \$opts{'help'},
    "i|interactive"                             => \$opts{'interactive'},
    "verbose"                                   => \$opts{'verbose'},
)  or usage();

# Give usage message.
usage() if $opts{'help'};

# Check that two required arguments are given
if ($#ARGV != 1) {
    print "ERROR: Must provide compset and filename\n";
    usage();
}
$data{'compset'}{'val'} = shift(@ARGV);
$data{'ic_file'}{'val'} = shift(@ARGV);

# Check for unparsed arguments
if (@ARGV) {
    print "ERROR: unrecognized arguments: @ARGV\n";
    usage();
}

if ( ! -w $data{'ic_file'}{'val'} ) {
    print "ERROR: Input file does NOT exist or NOT writable: $data{'ic_file'}{'val'}\n";
    usage();
}

# Error check the settings, and ask for them again if interactive mode set
foreach my $key ( keys(%data) ) {
  my $usedefault = "y";
  if ( $opts{'interactive'} ) {
    print "Enter $key: $data{$key}{'desc'}\n";
    print "Use default value of: $data{$key}{'val'}? (y/n) (default $usedefault)\n";
    if ( $data{$key}{'val'} eq $default ) {
       print "(value=\'$default\' means this value is NOT set and will NOT go on the file -- unless you respond with 'n')\n";
    }
    $usedefault = <STDIN>;
    chomp( $usedefault );
    if ( $usedefault eq "n" ) {
       print "Enter $key($data{$key}{'optname'} option)\n";
       $data{$key}{'val'} = <STDIN>;
       chomp( $data{$key}{'val'} );
    }
  }
  # If data required or string not empty -- make sure it matches
  if ( $data{$key}{'required'} || $data{$key}{'val'} ne $default ) {
     if ( $data{$key}{'val'} !~ /^$data{$key}{'match'}$/ ) {
       print "ERROR: $key has a bad value : $data{$key}{'optname'} = $data{$key}{'desc'}\n";
       die "Bad value for $key\n";
     }
  }
  if ( $opts{'verbose'} ) {
     print "$key = $data{$key}{'val'}\n";
  }
}
# Now add them to the file
foreach my $key ( keys(%data) ) {
  if ( $data{$key}{'val'} ne $default & $data{$key}{'goesonfile'}) {
     my $cmd = "ncatted -a $key,global,a,c,".$data{$key}{'val'}." ".$data{'ic_file'}{'val'};
     if ( $opts{'verbose'} ) {
        print "execute: $cmd\n";
     }
     if ( ! $opts{'debug'} ) {
        system( $cmd );
     }
  }
}
