#!/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 orthologer_conf.sh has not been loaded" 1>&2 && exit 255
#------------------------------------------------
set -u

export ENV_IS_BAD=0

#-----------------------------------------------
# check file size excluding lines starting with '#'
# args: <fnam> [<fnamref> <fszlim>]
#   <fnam>      file name
#   <fnamref>   reference file name
#   <fszlim>    min fraction n(lines)/n(lines ref) - default 0.01
#-----------------------------------------------
check_size() {
    [[ $# -lt 1 ]] && fatal_msg "check_size() invalid nr of arguments = $#"
    local fnam="$1"
    local fnamref=
    local fszlim="0.01"
    [[ $# -ge 2 ]] && fnamref="$2"
    [[ $# -eq 3 ]] && fszlim="$3"

    # save messages limit
    local maxmsg=$MAX_MESSAGES

    local size=$(grep -v '^#' "$fnam" | wc -l)
    
    if [[ $size -eq 0 ]]; then
        cnt_warn_msg "file contains no data : $fnam"
        return 1
    fi

    if [[ -f "$fnamref" ]]; then
        local refsize=$(grep -v '^#' "$fnamref" | wc -l)
        local frac=$(calc $size/$refsize)
        local isok=$(awk "BEGIN{ if ($frac > $fszlim) print 1; else print 0 }")
        [[ $isok -eq 0 ]] || return 0
        local bfnam=$(basename "$fnam")
        local bfnamref=$(basename "$fnamref")

        # warning msgs concerning file size relative to ref
        cnt_warn_msg "file $bfnam contains few data lines ($size) relative $bfnamref ($refsize), limit = $fszlim, fraction = $frac"
        return 1
    fi
    return 0
}

#-----------------------------------------------
# check end tag
# NOTE: end tag is hard coded
#       see create_end()
#-----------------------------------------------
check_end() {
    [[ $# -gt 0 ]] || return 0
    grep -q "^#END" "$1" || { cnt_warn_msg "file is missing end tag #END : $1"; return 1; }
    return 0
}

#-----------------------------------------------
# check file contents, depending on flag
#  0 - file existance
#  1 - end tag
#  2 - size
#-----------------------------------------------
check_file_cont() {
    [[ $# -lt 2 ]] && fatal_msg "check_file_cont() invalid nr of arguments = $#"
    local fnam="$1"
    local chkwhat=$2
    local fnamref=
    local fsz=0.01
    [[ $# -ge 3 ]] && fnamref="$3"
    [[ $# -eq 4 ]] && fsz="$4"

    # always check existance
    if [[ ! -f "$fnam" ]]; then
	    cnt_warn_msg "file does not exist : $fnam"
	    return 1
    fi
    [[ $chkwhat -gt 0 ]] || return 0
    
    # check for end tag
    if [[ $chkwhat -ge 1 ]]; then
	    check_end "$fnam"
	    [[ $? -ne 0 ]] && return 2
    fi

    # check for file size
    if [[ $chkwhat -ge 2 ]]; then
        check_size "$fnam" "$fnamref" "$fsz"
        [[ $? -ne 0 ]] && return 3
    fi

return 0
}

#-----------------------------------------------
# check pipeline environment
#-----------------------------------------------
check_environment() {
    CHECK_COUNTER=0
    local ec=0
    if [[ $VERBOSE -eq 0 ]]; then
        verify_setup >& /dev/null
        ec=$?
    else
        verify_setup
        ec=$?
    fi
    ENV_IS_BAD=$ec

    msg="${FACE_BOLD}ENVIRONMENT${FACE_NORMAL}"
    [[ $ec -eq 0 ]] && ok_status_msg "$msg" || error_status_msg "$msg"
}

#------------------------------------------------
# get all steps, if any
#-----------------------------------------------
check_pipeline() {
    [[ $# -gt 0 ]] || fatal_msg "check_setup: no valid step given"
    local steps=$*

    echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
    # 1. check environment
    check_environment

    # 2. check all steps
    local s=
    for s in $steps; do
        local f=check_step_${s,,}
        isfunc $f || continue #{ warn_msg "missing check function ${f}()"; continue; }
        $f
    done
    echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"

    # If environment is bad, print special message
    if [[ $ENV_IS_BAD -ne 0 ]]; then
        echo
        warn_msg "The environment check failed."
        warn_msg "Check details using the following:"
        warn_msg ""
        warn_msg "> ./pipeline.sh [-t <todofile>] -xpV"
        warn_msg ""
        warn_msg "This check should fail and show"
        warn_msg "what exactly is the problem."
        echo
    fi
}
