#!/usr/bin/env bash
#
# orthologer - Pipeline for deducing orthology from fasta files.
# Copyright (C) 2005-2023 E. Zdobnov lab: F. Tegenfeldt
# <fredrik.tegenfeldt@unige.ch> based on code by E. Kriventseva
#
# This file is part of orthologer.
#
# orthologer is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# orthologer is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with orthologer.  If not, see <http://www.gnu.org/licenses/>.
#
#-----------------------------------------------------
# general setup independent of batch job engine
#-----------------------------------------------------

#--- check if environment is ok -----------------
[ "${LOADED_COMMON_PIPELINE_SH+1}" == "" ] && echo "ERROR $0 : main config has not been loaded" 1>&2 && exit 255
#------------------------------------------------

#-----------------------------------------------------
# set global variables defined in scheduler_common.sh
#-----------------------------------------------------
CMD_BSUB=$(/usr/bin/which bsub 2>/dev/null)
CMD_BJOBS=$(/usr/bin/which bjobs 2>/dev/null)
CMD_BKILL=$(/usr/bin/which bkill 2>/dev/null)

SJ_BATCH_JOBID_NAME="LSB_JOBID"
sj_scheduler_init() {
    [ ${#CMD_BSUB}  -gt 0 ] || { error_msg "LSF scheduler -> missing 'bsub' command";   return 255; }
    [ ${#CMD_BJOBS} -gt 0 ] || { error_msg "LSF scheduler -> missing 'bjobs' command";  return 255; }
    [ ${#CMD_BKILL} -gt 0 ] || { error_msg "LSF scheduler -> missing 'bkill' command";  return 255; }
    return 0
}

#-----------------------------------------------------
# submit the job - required by sj_submit()
#-----------------------------------------------------
sj_submit_job() {
    # create full names of stdout and stderr
    # %J expands to job id
    local stdout="${SJ_JOBSTDOUT}_%J.log"
    local stderr="${SJ_JOBSTDERR}_%J.log"

    local jobstr=
    local err=0

    # do the submission
    jobstr=$($CMD_BSUB -o "$stdout" -e "$stderr" -n $SJ_NCPUPROC -R "span[ptile=$SJ_NCPUPROC]" -J "$SJ_JOBLABEL" $SJ_SCHEDOPTS < "$SJ_BATCH_SCRIPT")
    err=$?
    
    rm -f "$SJ_BATCH_SCRIPT"
    
    if [ $err -ne 0 ]; then
        error_msg "$SJ_JOBLABEL : slurm job submission failed with error code $err, sbatch output: $jobstr"
        return $err
    fi

    # parse jobid
    # line expected is:
    #   Job <jobid> is submitted to [default queue <normal>].
    SJ_BATCH_JOBID=$(echo $jobstr | cut -f 2 -d ' ' | grep -o '[0-9]*')
    err=$?
    if [ $err -ne 0 ]; then
        error_msg "unable to parse job submit string from slurm (ec=$err)"
        echo_err "---"
        echo_err "$jobstr"
        echo_err "---"
        fatal_msg "aborting!"
    fi
}

#-----------------------------------------------------
# run interactive job
#-----------------------------------------------------
sj_interactive_job() {
    # create full names of stdout and stderr
    # %J expands to job id
    local stdout="${SJ_JOBSTDOUT}_%J.log"
    local stderr="${SJ_JOBSTDERR}_%J.log"

    # clear batch jobid
    SJ_BATCH_JOBID=

    # run interactive job
    # this will run the job on the cluster and wait until finished
    # hence no SJ_BATCH_JOBID
    $CMD_BSUB -I -o "$stdout" -e "$stderr" -n $SJ_NCPUPROC -R "span[ptile=$SJ_NCPUPROC]" -J "$SJ_JOBLABEL" $SJ_SCHEDOPTS < "$SJ_BATCH_SCRIPT"
    ec=$?
    
    rm -f "$SJ_BATCH_SCRIPT"
    return $ec
}

sj_accounting() {
    error_msg "job accounting not implemented (LSF)"
    return 255
}

# this lists all jobs for the given user and optional job id's
sj_list_jobs() {
    [ $# -gt 0 ] || return 0
    local uid=$1
    local jobids=

    # jobids here is a CSV string - should be a space separated string
    [ $# -gt 1 ] && jobids="$(tokenize "," $2)"

    #Example output from bjobs:
    #JOBID  USER   STAT  QUEUE    FROM_HOST    EXEC_HOST     JOB_NAME SUBMIT_TIME
    #2685   siliu  RUN   regular   yslogin1-ib 32*ys0101-ib  pre       Aug 11 14:06
    local a=()
    local line=
    $CMD_BJOBS -u $uid $jobids 2>/dev/null | tail -n +2 |
    while read line; do
        a=( $(echo $line) )
        [ ${#a[@]} -gt 2 ] || continue
        local jid=${a[0]}
        local status=${a[2]}
        local ok=0
        # ignore all entries but those for RUN and PEND
        [ "$status" == "RUN"  ] && ok=1
        [ "$status" == "PEND" ] && ok=1
        [ $ok -eq 1 ] && echo $jid
    done
    return 0
}

sj_cancel_jobid() {
    [ $# -gt 0 ] || return 0
    $CMD_BKILL $*
}

export -f sj_scheduler_init
export -f sj_submit_job
export -f sj_interactive_job
export -f sj_cancel_jobid
export -f sj_list_jobs
export -f sj_accounting

