#!/bin/bash -u
#
# 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/>.
#
#
# Run given aligner algorithm.
# The command line format is
#   run_alignment.sh <label Query>,<label DB>
#
#--- check if environment is ok -----------------
[[ "${LOADED_COMMON_ORTHODB_SH+1}" == "" ]] && echo "ERROR $0 : main config has not been loaded" 1>&2 && exit 255
#------------------------------------------------
[[ $# -eq 1 ]] || fatal_msg "usage: $0 <label Query,label DB,nthreads>;<...>;<...>;..."
input="$1"
inparr=( $(tokenize ";" $input) )

#OUTPUT_MAYBE_BRH=0
if [[ ${ALIGNMENT_LABEL} == "MMSEQS" ]]; then
    if (( MMSEQS_ALIGN_MODE == 1 )); then
        # use 'mmseqs search'
        ALIGNMENT_SCRIPT=${ALIGNMENT_SCRIPT//_mmseqs/_smmseqs}
#    elif (( MMSEQS_ALIGN_MODE == 2 )); then
#        # use 'mmseqs rbh' if A and B are different, otherwise 'mmseqs search'
#        ALIGNMENT_SCRIPT=${ALIGNMENT_SCRIPT//_mmseqs/_mmseqs_brh}
#        OUTPUT_MAYBE_BRH=1
    fi
fi

info_msg "Alignment script: $ALIGNMENT_SCRIPT"

# setup environment
# 1. alignment options common to all
# 2. tmp files to be used for all
__ALIGNMENT_OPTS=""
source $ALIGNMENT_SCRIPT

nok=0
nerr=0

# make tmp fasta and output files
tmpout=""
tmpdir=""

tmp_make_dir tmpdir "align"        || exit 255

info_msg "Sequences DB dir : $DIR_PROJECT_SEQUENCES" 

# assoc array of files to copy
# results[<tmpfile>] = <target file>

move_files="echo 'move files'"


fsAprev=""
fsBprev=""

# loop over all pairs of A,B
for args in ${inparr[@]}; do
    argsarr=( $(tokenize "," $args) )
    [[ ${#argsarr[@]} -eq 3 ]] || fatal_msg "run_alignment.sh: invalid input ($input), expected comma separated list <idA0,idB0,N;idA1,idB2,N;...> but got <$input>";

    # label pair A,B
    A="${argsarr[0]}"
    B="${argsarr[1]}"

    # check if labels are equal
    equal=0
    [[ $A == $B ]] && equal=1

    # nr of threads
    nthreads=${argsarr[2]}

    # temporary output with the final name
    tmpout="$tmpdir/${A}_${B}.${EXT_ALIGN}"
    
    info_msg "Starting alignment job <$A,$B> with N(threads)=$nthreads"

    # get fasta names - without potential compression extension
    fsA="${DIR_PROJECT_SEQUENCES}/${A}.${EXT_FASTA_SELECTED}"
    fsB="${DIR_PROJECT_SEQUENCES}/${B}.${EXT_FASTA_SELECTED}"

    # target file name
    pairfile="${DIR_PROJECT_PWC}/$A/${A}_${B}.${EXT_ALIGN}"

    # these will be softlinks to the original fasta
    tmpA="$tmpdir/${A}.${EXT_FASTA_SELECTED}"
    tmpB="$tmpdir/${B}.${EXT_FASTA_SELECTED}"
    
    # softlink DB files wrt tmpA and tmpB
    # this will also verify the existance of the formatdb files
    if [[ $fsA != $fsAprev ]]; then
        ln -sf  "$fsA" "$tmpA" || exit 255
        link_formatdb_files "$fsA" "$tmpA" || exit 255
    fi

    # check if A B are equal
    if (( equal == 0 )); then
        if [[ $fsB != $fsBprev ]]; then
            ln -sf  "$fsB" "$tmpB" || exit 255
            link_formatdb_files "$fsB" "$tmpB" || exit 255
        fi
    else
        # labels are the same -> use the same files as input
        tmpB="$tmpA"
    fi
    
    # run aligner script in a sub shell
    #( tmp_setup_trap && source "$ALIGNMENT_SCRIPT" "$tmpA" "$tmpB" "$tmpout" $nthreads )
    source "$ALIGNMENT_SCRIPT" "$tmpA" "$tmpB" "$tmpout" $nthreads
    if (( ALIGNMENT_EC == 0 )); then
        move_files="$move_files && mv -f $fAB $fAlign"
        nok=$((nok+1))
    else
        eval $move_files
        fatal_msg "failed finding alignment for key pair [$A,$B] with error $ec"
    fi
    ec=$?
    [[ -f "$tmpout" ]] || { eval $move_files; fatal_msg "no output file is found - $tmpout"; }
    if [[ $ec -eq 0 ]]; then
        move_files="$move_files && mv -f $tmpout $pairfile"
        nok=$((nok+1))
    else
        nerr=$((nerr+1))
    fi
    info_msg "DONE alignment job <$A,$B>, exit code = $ec"
    # save last A
    fsAprev="$fsA"
    fsBprev="$fsB"
    
done

# move all files
info_msg "MOVING FILES:"
eval $move_files
[[ $? -eq 0 ]] || nerr=$((nerr+1))

# check if any errors
[[ $nerr -eq 0 ]] || fatal_msg "Completed $nok succesfully and $nerr with errors"
info_msg "DONE"

###profile_report "ALIGNMENT"
