#!/bin/bash
#
#   Usage: setup-canesm [options] ver=hash runid=runid \
#                       [config=AMIP]
#                       [repo=dirpath] \
#                       [exp=EXP00] \
#                       [cmip=0] \
#          Quantities in square brackets are optional
#
# Purpose: Copy all files needed to compile and run CanESM into the current directory and optionally. 
#          A logfile for the run is written into ".setup-canesm.log" and a copy of this log is sent
#          to the run database.  
#          
# Options:
#   -x ...set -x
#   -c ...generate the default jobstring (for this commit) and compile 
#   -s ...save the default restart files using $runid
#   -r ...automatically submit the default jobstring (for this commit) after compilation
#   -a ...the combintation of saving, compiling and submitting, equivalent to "-csr"
#
# Variable definitions:
#   ver=HASH      ...HASH is the SHA1 checksum (or branch, tag, treeish) to extract from
#                    the git repository (e.g. a19i6yuij7)
#   runid=abc     ...abc is the runid for your run (normally three letters). This will be
#                    used in naming local files, and ultimately in saving executables later.
#   config=name   ...name is the name of a model configuration (currently one of "ESM" or "AMIP"). Defaults to AMIP.
#   repo=LOCATION ...LOCATION is the url or pathname to the git repository (defaults to git@gitlab.science.gc.ca:CanESM/CanESM5.git)
#   cmip=run_type ...run_type is type of the run (1 for production, 0 for development). Defaults to 0.
#                    "cmip" setting is propagated into "production" variable in canesm.cfg file.
#                    The effect of "cmip=1" is to alter DATAPATH_DB setting to target "cmip6" subset instead of the default database
#                    for runs on Hare/Brooks/Banting/Daley. 
#   srclnk=path   ...for ensembles, softlink to CCRNSRC code, rather than cloning individual repositories. NOT RECOMMENDED.
#   diagff_sfx=SFX  ...specify this to setup a diagnostics only directory, to do "diagnostics from the future" for an existing run. SFX
#                    will be used to name the directory and some path locations, and a unique config directory/branch.
#
# Examples:
#     Setup an AMIP development run off gitlab with RUNID=XXX:
#           setup-canesm ver=3be3649b0 runid=XXX 
#
#     Setup an ESM production run off gitlab with RUNID=yyy:
#           setup-canesm ver=3be3649b0 config=ESM runid=YYY cmip=1
#
#     Setup, save restarts, compile and submit an AMIP production run off commit 3be3649b0
#           setup-canesm -a ver=3be3649b0 config=AMIP runid=WWW cmip=1
#
# Neil Swart: 2017-09
#
# last updated 2019-03-07
########################################################################
# 1. Initialization and arguement parsing 
#
# Where we are starting, for later reference.
export WRK_DIR=`pwd` 

# An error funtion
bail(){
echo "${Runame}: *** ERROR *** $1"
exit 1
}

FULLPATH=`type $0|awk '{print $3}'` # pathname of this script
Runame=`basename $FULLPATH`

# Help message
usage() {
  err_exit=0
  while getopts e opt; do
    case $opt in
      e) err_exit=1 ;;
    esac
  done
  shift `expr $OPTIND - 1`

  [ -n "$1" ] && echo >&2 "${Runame}:" "$@"
  echo >&2 " "
  sed >&2 -n '/^###/q; s/^#$/# /; s/^ *$/# /; 3,$s/^# //p;' "$FULLPATH"
  if [ $err_exit -eq 0 ]; then
    exit
  else
    exit 1
  fi
}

# Set defaults

# runid for this run, used to set file names
CANESM_RUNID=''

# The version of code to extract and compile
CANESM_VER=''

# The particular configuration of the model to setup (ESM or AMIP). This
# controls which configuration files are extracted from the "config" directory
# in the CanESM repo.
CANESM_CONFIG='AMIP'

# The default location of the repository containing nemo source code
CANESM_REPO=git@gitlab.science.gc.ca:CanESM/CanESM5.git

# The default is development run type (=0)
CANESM_CMIP=0 ; export CANESM_CMIP

# No linking by default. If specified, will link to code
# instead of cloning repositories.
export CANESM_SRCLNK=''

# diag_sfx defines if this is a future diagnostics only setup
export CANESM_DFFSFX=''

export ALL=0
export COMPILE=0
export RUN=0
export SAVE=0

# process command line options
while getopts acsrn:m:r:hktvx opt
do
  case $opt in
    a) ALL=1 ;;
    c) COMPILE=1 ;;
    s) SAVE=1 ;;
    r) RUN=1 ;;
    x) set -x ;;
    h) usage ;;
    -) shift; break ;; # end of options
    ?) usage -e $USAGE   ;;
  esac
done
shift `expr $OPTIND - 1`

# Process the remaining command line args
for arg in "$@"; do
  case $arg in
    *=*) var=`echo $arg|awk -F\= '{printf "%s",$1}' -`
         val=`echo "$arg"|awk '{i=index($0,"=")+1;printf "%s",substr($0,i)}' -`
         # add this variable definition to the current environment
         [ -n "$var" ] && eval ${var}=\"\$val\" # preserve quoted assignments
         case $var in
             runid) CANESM_RUNID="$val" ;;       # The runid for this setup (three letters)
               ver) CANESM_VER="$val" ;;         # git commit, tag or branch
              repo) CANESM_REPO="$val" ;;        # location of git repository
            config) CANESM_CONFIG="$val" ;;      # name of subdir in which config lives
            cmip) CANESM_CMIP="$val" ;;          # run type ( 1 for production, 0 for development)
            srclnk) CANESM_SRCLNK="$val" ;;      # location to link ccrnsrc from
        diagff_sfx) CANESM_DFFSFX="$val" ;;      # name of "future diagnostics" directory suffix
                 *) bail "Invalid command line arg --> $arg <--" ;;
         esac
         ;;
    *) bail "Invalid command line arg --> $arg <--" ;;
  esac
done

[ -z "$CANESM_RUNID" ] && bail "A runid is required on the command line." || export CANESM_RUNID
[ -z "$CANESM_VER" ] && bail "A commit SHA1, tag or branch of the 'CanESM(5) repository' is required in the 'ver' field on the command line." || export CANESM_VER
[ -z "$CANESM_REPO" ] && bail "The source repository name is missing." || export CANESM_REPO
[ -z "$CANESM_CONFIG" ] && bail "You must specify one of: ver=ESM or ver=AMIP" || export CANESM_CONFIG
export CANESM_DFFSFX

# Print a message to make people feel fuzzy
printf "\n\n \t *** SETUP-CANESM *** \n\n \t Attempting to setup your run ${CANESM_RUNID}...\n"
printf "\t Cloning ${CANESM_REPO} and extracting revision  ${CANESM_VER} \n"
printf "\n \t ...standby... \n\n"
sleep 2

########################################################################
# 2. Cloning repositories to tmp space

if [ -z "$CANESM_SRCLNK" ]; then
    export TMP_ROOT=/tmp/setup-canesm-$$
    mkdir -p -m 1755 ${TMP_ROOT}
    cd $TMP_ROOT

    # Checkout the CamESM5 "super repo" from the target location
    git clone $CANESM_REPO CanESM|| bail "Failed to clone $CANESM_REPO ...is this a valid & accessible repository?"
    cd CanESM

    git checkout $CANESM_VER || bail "Failed to checkout ${CANESM_VER}...is this a valid reference in CanESM5 (SHA1, branch or tag)?"
    git submodule update --recursive --init --checkout || bail "Problem checking out submodules from CanESM super repo. Check that ${CANESM_VER} is a working version of the model"

    if [ -s CCCma_tools/tools/adv-setup ]; then 
     .  CCCma_tools/tools/adv-setup
    else
      echo "WARNING: CCCma_tools/tools/adv-setup/adv-setup does not exist!...using adv-setup.v1.0 (this is normal for pre-Dec 2017 commits)"
      . adv-setup.v1.0
    fi

else
    echo "Linking not cloning!"
    . $CANESM_SRCLNK/CanESM/CCCma_tools/tools/adv-setup
fi
