#!/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/>.
#
#--- check if environment is ok -----------------
[ "${LOADED_COMMON_PIPELINE_SH+1}" == "" ] && echo "ERROR $0 : main config has not been loaded" 1>&2 && exit 255
#------------------------------------------------

# make sure tmp file cleaning works
tmp_setup_trap

# get args
[[ $# -eq 1 ]] || fatal_msg "$0 - usage <node,inppairs,nthreads>"
input="$1"
inparr=( $(tokenize "," $input) )
[[ ${#inparr[@]} -eq 3 ]] || fatal_msg "invalid input ($input) to run_mergeinpar.sh, expected comma separated list <node,inppairs,Nthreads>";

# get args
lblnode="${inparr[0]}"   # todo label
inputPairData="${inparr[1]}"  # input pairs - only valid if MERGEINPAR step
nt="${inparr[2]}"        # nr of threads

# nr of threads, cap it to nr of cores available on the machine
nthreads=$(get_nthreads $nt)

optNograb=""
## if root and node are not equal, do not allow 'grabbing'
##[[ "$lblroot" == "$lblnode" ]] || optNograb="--nograb"

# check where we come from
extclin=""
extinp=""
extclout=""

usropts=""

# PWC option if pairwise
optpwc=""
# inparalog data to be used
finparData=""

# STEP_ID may be MERGEINPAR or MERGEINPARSEL
if   [[ "$STEP_ID" == "MERGEINPAR"    ]]; then
    extclin=${EXT_CLUSTER_RAW}
    extinp=${EXT_INPAR}
    extclout=${EXT_CLUSTER_INPAR}
    usropts="$OPTS_MERGEINPAR"
    optpwc="--pwc $DIR_PROJECT_PWC"
    finparData="$inputPairData"
    #------------------------------
    # set input pairs file name and possibly create it
    # use stepid MAKEBRH -> half matrix, excluding diagonal
    # name returned in GENERATED_PAIR_FILE
    ##create_pairwise_file "MAKEBRH" "0" "$lblnode"
    
    # define input depending on tree mode
    # 1. no tree
    # -> first try Cluster/<node>.inpar
    # -> else todo/<node>.todo
    # 2. tree
    # -> first try todo/<node>.pairs_<hash>
    # -> else todo/<node>.todo
    #
    ##ftodo="${DIR_PROJECT_TODO}/${lblnode}.todo"
    ##fpairs="${DIR_PROJECT_TODO}/${lblnode}.$EXT_PAIRS_TREE"
    ##finpar="${DIR_PROJECT_CLUSTER}/${lblnode}.${extinp}"
    
    # default, use pair file
    ##finparData="$fpairs"
    ##optpwc="--pwc $DIR_PROJECT_PWC"
    ##[[ -f $finpar ]] && {
    ##    # .inpar file exists - use it!
    ##    finparData="$finpar"
    ##    optpwc=""
    ##}
    #------------------------------

    
elif [[ "$STEP_ID" == "MERGEINPARSEL" ]]; then
    extclin=${EXT_CLUSTER_INPAR}
    extinp=${EXT_INPAR_SELECTED}
    extclout=${EXT_CLUSTER}
    usropts="$OPTS_MERGEINPARSEL"
    # here it's not pairwise
    finparData="${DIR_PROJECT_CLUSTER}/${lblnode}.${extinp}"
else
    fatal_msg "run_mergeinpar.sh got bad step id = $STEP_ID"
fi

fclust="${DIR_PROJECT_CLUSTER}/${lblnode}.${extclin}"

# for output do not add comp ext
output="${DIR_PROJECT_CLUSTER}/${lblnode}.${extclout}"
unres="${DIR_PROJECT_CLUSTER}/${lblnode}.${extclout}.unresolved"

# check files
check_file     "$0" "$finparData"       || exit 255
check_file     "$0" "$fclust"           || exit 255
check_file_exe "$0" "$EXE_MERGEINPAR"   || exit 255

# check variables
check_variable "$0" "MIN_OVERLAP"          || exit 255
check_variable "$0" "MERGEINPAR_FHITSMAX"  || exit 255
check_variable "$0" "MERGEINPAR_FCLUSTMIN" || exit 255
check_variable "$0" "MERGEINPAR_FSPECMIN"  || exit 255

# run program
opts="$OPTS_MERGEINPAR -T $nthreads --fspecmin $MERGEINPAR_FSPECMIN --fhitsmax $MERGEINPAR_FHITSMAX"
opts="$opts --fclustmin $MERGEINPAR_FCLUSTMIN --overlap $MIN_OVERLAP $optNograb $optpwc"

tmpfile=""
tmpout=""
tmp_make tmpfile mergeinpar
tmp_make tmpout  mergeinpar

tmplog="${tmpfile}.log"
tmp_add_file "$tmplog"

startdate=$(date)
tA=$(time_msec)
ec=0

inpind=""
if [[ $TREE_ENABLED == "1" ]]; then
    if [[ -n $TREE_ROOT_CLADE ]]; then
        info_msg "set index file to $DIR_PROJECT_CLUSTER/${TREE_ROOT_CLADE}.index"
        [[ -f "$DIR_PROJECT_CLUSTER/${TREE_ROOT_CLADE}.index" ]] && inpind="-i $DIR_PROJECT_CLUSTER/${TREE_ROOT_CLADE}.index"
    else
        error_msg "odd - tree is enabled but TREE_ROOT_CLADE is not set"
    fi
else
    info_msg "tree not enabled"
fi


if (( MERGEINPAR_USE_HUGEMEM == 0 )); then
    info_msg "using regular memory pages"
    info_msg "command: $EXE_MERGEINPAR $opts -C "$fclust" -I "$finparData" $inpind -o ${tmpfile} -u $unres"
    $EXE_MERGEINPAR $opts -C "$fclust" -I "$finparData" $inpind -o ${tmpfile} -u $unres > $tmplog
    ec=$?
else
    if [[ -f $LIB_HUGEMEM ]]; then
        info_msg "using HUGEMEM with library $LIB_HUGEMEM"
        LD_PRELOAD=$LIB_HUGEMEM HUGETLB_MORECORE=yes $EXE_MERGEINPAR $opts -C "$fclust" -I "$finparData" $inpind -o ${tmpfile} -u $unres > $tmplog
        ec=$?
    else
        warn_msg "HUGEMEM was requested but library is missing at: $LIB_HUGEMEM"
        warn_msg "running without HUGEMEM enabled"
        $EXE_MERGEINPAR $opts -C "$fclust" -I "$finparData" -o ${tmpfile} -u $unres  $inpind > $tmplog
        ec=$?
    fi
fi

if [[ $ec -ne 0 ]]; then
	error_msg "$0 : mergeinpar failed with ec = $ec"
	echo "inpar file   :  $finparData"
	echo "cluster file :  $fclust"
	echo "partial output so far:"
	head -n 100 $tmpfile
    echo "..."
    tail -n 100 $tmpfile
    echo
    echo "====================================================="
    echo
    echo "logfile      :"
    cat $tmplog
	exit 255
fi
dT=$(delta_time $tA)

# add header and footer to file
add_header_footer $0 "$tmpfile" "$tmpout" "$startdate" $dT "\"$EXE_MERGEINPAR $opts -T $nthreads -C $fclust -I $finparData $inpind -o ${output} -u $unres\""
[[ $? -eq 0 ]] || fatal_msg "failed mergeinpar"

# copy and chmod log file
mv -f $tmplog "${output}.log" 
chmod 644 "${output}.log"

# move output file
mv -f $tmpout $output
chmod 644 $output

