#!/bin/sh
# set -xv
#
#  Submits job to loadleveler.
#
# A temporary job script is created for the submission and then removed 
# at the end of this script. 
#

echo "----- starting submit_ll_job -----" 1>&2

joboption_lrms=ll

# ARC1 passes first the config file.
if [ "$1" = "--config" ]; then shift; ARC_CONFIG=$1; shift; fi

basedir=`dirname $0`
basedir=`cd $basedir > /dev/null && pwd` || exit $?

pkglibdir="$basedir/../../lib/arc"
pkglibdir=`cd $pkglibdir > /dev/null && pwd` || exit $?

. ${pkglibdir}/configure-ll-env.sh || exit $?
. ${pkglibdir}/submit_common.sh || exit $?

joboption_localtransfer='no'

##############################################################
# Parse grami file, read arc config
##############################################################

init $1

# GD enforce this for the moment
RUNTIME_FRONTEND_SEES_NODE=''
RUNTIME_NODE_SEES_FRONTEND='yes'

##############################################################
# Zero stage of runtime environments
##############################################################

RTE_stage0

LL_SUB='llsubmit'
if [ ! -z "$LL_BIN_PATH" ] ; then
  LL_SUB=${LL_BIN_PATH}/${LL_SUB}
fi

mktempscript

##############################################################
# Start job script
##############################################################
echo "# LL batch job script built by grid-manager" > $LRMS_JOB_SCRIPT

# job name for convenience
if [ ! -z "${joboption_jobname}" ] ; then
  jobname=`echo "$joboption_jobname" | \
           sed 's/^\([^[:alpha:]]\)/N\1/' | \
           sed 's/[^[:alnum:]]/_/g' | \
	   sed 's/\(...............\).*/\1/'`
  echo "# @ job_name = $jobname" >> $LRMS_JOB_SCRIPT
fi

echo "LL jobname: $jobname" 1>&2

echo "# @ output = ${joboption_directory}.comment" >> $LRMS_JOB_SCRIPT
echo "# @ error = ${joboption_directory}.comment" >> $LRMS_JOB_SCRIPT

# Project account number for accounting
if [ ! -z "${joboption_rsl_project}" ] ; then
  echo "# @ account_no = $joboption_rsl_project" >> $LRMS_JOB_SCRIPT
fi

##############################################################
# (non-)parallel jobs
##############################################################
if [ -z "$joboption_count" ] || [ "$joboption_count" -le 1 ] ; then
  joboption_count=1
else
  #we only support serial jobs on LL
  echo 'ERROR: No support for parallel jobs' 1>&2
fi

##############################################################
# Execution times (obtained in seconds)
##############################################################
# cputime/walltime is obtained in seconds via $joboption_cputime and $joboption_walltime

if ( [ -n "$joboption_cputime" ] && [ $joboption_cputime -gt 0 ] ) ; then
  joboption_cputime_hard=$(($(( $joboption_cputime * $time_hardlimit_ratio))+30))
fi
if [ -n "$joboption_walltime" ] ; then  
  if [ $joboption_walltime -lt 0 ] ; then
    joboption_walltime=0
  fi
  joboption_walltime_hard=$(($(( $joboption_walltime * $time_hardlimit_ratio))+30))
fi

echo "# @ job_cpu_limit = ${joboption_cputime_hard} , ${joboption_cputime}" >> $LRMS_JOB_SCRIPT
echo "# @ wall_clock_limit = ${joboption_walltime_hard} , ${joboption_walltime}" >> $LRMS_JOB_SCRIPT


##############################################################
# Requested memory (mb)
##############################################################
# There are soft and hard limits for virtual memory consumption in LL

if [ -n "$joboption_memory" ] ; then
  joboption_memory_hard=$(( $joboption_memory * $memory_hardlimit_ratio ))
  requirements="(Memory > ${joboption_memory_hard})"
  preferences="(Memory > ${joboption_memory})"
  echo "# @ requirements = ${requirements}" >> $LRMS_JOB_SCRIPT
  echo "# @ preferences = ${preferences}" >> $LRMS_JOB_SCRIPT
else
  joboption_memory="1 mb"
fi

##############################################################
# Consumable resources
#############################################################
echo "# @ resources = ConsumableCpus($joboption_count) ConsumableMemory(${joboption_memory})" >> $LRMS_JOB_SCRIPT

##############################################################
# Override umask
##############################################################
#echo "umask 077" >> $LRMS_JOB_SCRIPT

#echo 'exec > /var/tmp/grid-job-output.$$ 2>&1' >> $LRMS_JOB_SCRIPT

##############################################################
# Add environment variables
##############################################################

add_user_env

##############################################################
# Check for existence of executable,
##############################################################
if [ -z "${joboption_arg_0}" ] ; then
  echo 'Executable is not specified' 1>&2
  exit 1
fi

if [ ! "$joboption_localtransfer" = 'yes' ] ; then
  program_start=`echo ${joboption_arg_0} | cut -c 1 2>&1`
  if [ "$program_start" != '$' ] && [ "$program_start" != '/' ] ; then
    if [ ! -f $joboption_directory/${joboption_arg_0} ] ; then 
      echo 'Executable does not exist, or permission denied.' 1>&2
      echo "   Executable $joboption_directory/${joboption_arg_0}" 1>&2
      echo "   whoami: "`whoami` 1>&2
      echo "   ls -l $joboption_directory/${joboption_arg_0}: "`ls -l $joboption_directory/${joboption_arg_0}`
      exit 1
    fi
    if [ ! -x $joboption_directory/${joboption_arg_0} ] ; then 
      echo 'Executable is not executable' 1>&2
      exit 1
    fi
  fi
fi

##################################################################
#Read queue from config or figure out which queue to use
##################################################################
if [ ! -z "${joboption_queue}" ] ; then
  class=$joboption_queue
else
  #if queue is not set we must choose one
  LL_CLASS='llclass -l'
  if [ ! -z "$LL_BIN_PATH" ] ; then
    LL_CLASS=${LL_BIN_PATH}/${LL_CLASS}
  fi
  queue_names=`${LL_CLASS}|grep Name|awk '{split($0,field," ");print field[2]}'`

  for queue in $queue_names
  do
    queue_time=`${LL_CLASS} ${queue}|grep Wall_clock_limit|awk '{split($0,field,"(");print field[2]}'|awk '{split($0,field," ");print field[1]}'` 
    queue_times[$queue_time]=$queue_time
    queue_names_ar[$queue_time]=$queue
  done

  #default will be shortest queue
  if [! -n "$joboption_walltime" ] ; then  
    joboption_walltime_hard=1
  fi
  
  for j in ${queue_times[@]}
  do
    class=${queue_names_ar[${j}]}
    if ["${joboption_walltime_hard}" -lt "${j}"]; then 
      break
    fi
  done
fi

echo "# @ class=${class}" >> $LRMS_JOB_SCRIPT


###################################################################
#Queue job
#No mail notification
##################################################################
echo "# @ notification = never" >> $LRMS_JOB_SCRIPT
echo "# @ queue" >> $LRMS_JOB_SCRIPT

#######################################################################
# copy information useful for transfering files to/from node directly
#######################################################################
if [ "$joboption_localtransfer" = 'yes' ] ; then
   setup_local_transfer
fi

setup_runtime_env

###################################################################
#setup soft limit trap
##################################################################
echo "trap \"echo 'exitcode=24'>>\$RUNTIME_JOB_DIAG;exit(24)\" SIGXCPU" >> $LRMS_JOB_SCRIPT


##############################################################
# Add std... to job arguments
##############################################################
include_std_streams

##############################################################
#  Move files to local working directory (job is done on node only)
#  RUNTIME_JOB_DIR -> RUNTIME_LOCAL_SCRATCH_DIR/job_id
##############################################################
move_files_to_node

echo "" >> $LRMS_JOB_SCRIPT
echo "RESULT=0" >> $LRMS_JOB_SCRIPT
echo "" >> $LRMS_JOB_SCRIPT


#####################################################
#  Download input files
####################################################
download_input_files

##############################################################
#  Skip execution if something already failed
##############################################################
echo "" >> $LRMS_JOB_SCRIPT
echo "if [ \"\$RESULT\" = '0' ] ; then" >> $LRMS_JOB_SCRIPT
echo "echo \"runtimeenvironments=\$runtimeenvironments\" >> \"\$RUNTIME_JOB_DIAG\"" >> $LRMS_JOB_SCRIPT

##############################################################
#  Runtime configuration
##############################################################

RTE_stage1

if [ -z "$RUNTIME_NODE_SEES_FRONTEND" ] ; then
  echo "Nodes detached from gridarea are not supported yet" 1>&2
  rm -f "$LRMS_JOB_SCRIPT" "$LRMS_JOB_OUT" "$LRMS_JOB_ERR"
  exit 1
fi

##############################################################
#  Execution
##############################################################
cd_and_run

echo "fi"  >> $LRMS_JOB_SCRIPT
##############################################################
#  Runtime (post)configuration at computing node
##############################################################
configure_runtime

#####################################################
#  Upload output files
####################################################
upload_output_files

##############################################################
#  Move files back to session directory (job is done on node only)
#  RUNTIME_JOB_DIR -> RUNTIME_LOCAL_SCRATCH_DIR/job_id
##############################################################
move_files_to_frontend

#######################################
#  Submit the job
#######################################
echo "ll job script built" 1>&2

# Execute sub command
cd "$joboption_directory"
echo "LL script follows:" 1>&2
cat "$LRMS_JOB_SCRIPT" 1>&2
echo "" 1>&2

${LL_SUB} $LRMS_JOB_SCRIPT 1>$LRMS_JOB_OUT 2>$LRMS_JOB_ERR

if [ $? -eq '0' ] ; then
   echo "LRMS_JOB_OUT is $LRMS_JOB_OUT"
   job_id=`cat $LRMS_JOB_OUT | awk '{split($0,field,"\"");print field[2]}'`.0
   if [ "${job_id}" = "" ] ; then
      echo "job *NOT* submitted successfully!" 1>&2
      echo "failed getting the LL jobid for the job!" 1>&2
   else
      echo "joboption_jobid=$job_id" >> $arg_file
      echo "job submitted successfully!" 1>&2
      echo "local job id: $job_id" 1>&2
      # Remove temporary job script file      
      rm -f $LRMS_JOB_SCRIPT $LRMS_JOB_OUT $LRMS_JOB_ERR
      echo "----- exiting submit_ll_job -----" 1>&2
      echo "" 1>&2
      exit 0
   fi
else
  echo "job *NOT* submitted successfully!" 1>&2
  echo "got error code from llsubmit!" 1>&2
fi

echo "Output is:" 1>&2
cat $LRMS_JOB_OUT 1>&2
echo "Error output is:"
cat $LRMS_JOB_ERR 1>&2
rm -f $LRMS_JOB_SCRIPT $LRMS_JOB_OUT $LRMS_JOB_ERR

echo "----- exiting submit_ll_job -----" 1>&2
echo "" 1>&2
exit 1
