#!/bin/bash

########################################
# test executable programs like mlocarna and locarnate
#
# Test whether selected calls work and produce the
# expected result.
#
# (Changes in the header version string of mlocarna are ignored, such
# that the expected test results don't have to be updated with every
# version change.)
#

if [ "$1" = "--generate-references" ] ; then
    GENERATE_OUTPUT=true
else
    GENERATE_OUTPUT=false
fi
## Test mlocarna and locarnate

## perform pseudo installation in subdir bin

if [ -e bin ] ; then rm -rf bin ; fi
mkdir bin

## top level directory of the locarna source
# ---- get the top level by going two levels up from srcdir
topdir=$srcdir/../..

testsdir=$topdir/src/Tests

## prefix links to bin files by another ../ since the links reside in bin
ln -sf ../$topdir/src/Utils/mlocarna bin/mlocarna
ln -sf ../$topdir/src/Utils/locarnate bin/locarnate
ln -sf ../../locarna.bin bin/locarna
ln -sf ../../locarna_p bin/locarna_p
ln -sf ../../sparse bin/sparse
ln -sf ../../locarna_rnafold_pp bin/locarna_rnafold_pp
ln -sf ../../exparna_p bin/exparna_p

ln -sf $topdir/lib . # also put perl lib modules in the right place


## put bin in PATH
export PATH=`pwd`/bin:$PATH

DIFFERENCES=false

## ----------------------------------------
## call test and compare output
##
## @param $1 the name of the test; shall not contain special symbols
## and white space, since this is used to derive file names
## @param $2 target directory, which is wiped after the test
## @param $3 result file, which is compared after test (or used to generate file)
## @param $4 options for diff
## @param $5-$last  command to call
##
## compare to (or generate) files src/Tests/$name.testresult
function calltest {
    name="$1"
    tgtdir="$2"
    resultfile="$3"
    diffopts="${4:-"--normal"}"

    reference_resultsfile=$testsdir/$name.testresult

    shift 4

    echo "============================================================"
    echo TEST $name
    echo CALL $*
    echo

    if $* ; then
        if [ -e "$reference_resultsfile" ] ; then
            if diff "$resultfile" "$reference_resultsfile" "${diffopts}"; then
                echo "==================== OK"
            else
                DIFFERENCES=true
                echo "==================== DIFFERENT"
            fi
        else
            echo "WARNING: file '$reference_resultsfile' does not exist!"
                echo "==================== NO_REFERENCE"
            DIFFERENCES=true
        fi

        if $GENERATE_OUTPUT ; then
            echo "Write new reference '$reference_resultsfile'."
            \cp $resultfile "$reference_resultsfile"
        fi

    else
        echo "==================== FAIL"
        rm -rf $tgtdir
        exit -1
    fi

    rm -rf $tgtdir
}

function mlocarna_calltest {
    name=$1
    shift
    calltest $name test.out test.out/results/result.aln -I'^CLUSTAL W --- LocARNA [0123456789]\.[0123456789]\.[0123456789].*$' $* --tgtdir test.out
}

## ========================================
## test mlocarna
##

# examples directory
exdir=$topdir/Data/Examples

# check standard usage with alifold consensus (similar to web server)
mlocarna_calltest mlocarna-archaea-alifold \
         mlocarna $exdir/archaea.fa --alifold-cons \
         -p 0.05 --max-diff 10

# check constraints
mlocarna_calltest mlocarna-haca-constraints \
         mlocarna $exdir/haca.snoRNA.fa -p 0.05 \
         --max-diff 20

# check mlocarna sparse
mlocarna_calltest mlocarna-sparse \
         mlocarna $exdir/archaea.fa --sparse -p 0.05 \
         --max-diff 10

# check probabilistic mode and stockholm
mlocarna_calltest mlocarna-probabilistic \
         mlocarna $exdir/archaea.fa --probabilistic \
         --consistency-transformation -p 0.05  --max-diff 10 --stockholm

# check many threads, and local folding and max-diff-aln
mlocarna_calltest mlocarna-threads \
         mlocarna $exdir/SECIS_15.fa  --threads 32 --alifold \
         --plfold-span 50 --max-diff 10 --max-diff-aln $exdir/SECIS_15_ref.aln

# check anchor constraints from bed file
mlocarna_calltest mlocarna-bed-anchors \
         mlocarna --alifold \
         --anchor-constraints $exdir/haca.snoRNA_anchor.bed \
         $exdir/haca.snoRNA.fa

# check realign
mlocarna_calltest mlocarna-realign \
         mlocarna --realign $exdir/example-realign.aln


## ========================================
## test locarnate (requires t_coffee to succeed)
##
calltest locarnate test_results test_results/mult/tcoffee.aln -I'^CLUSTAL FORMAT for T-COFFEE Version_' \
         locarnate $exdir/archaea.fa

if [ -d "test_results" ] ; then
    rm -rf test_results
fi
if [ -e "input.dnd" ] ; then
    rm -f input.dnd
fi

## ========================================
## test exparna_p
##

outdir="locarna.out"
outfile="$outdir/result"

mkdir $outdir
calltest exparna_p $outdir $outfile "" exparna_p $exdir/mouse.fa $exdir/human.fa -q --output-epm-list=$outfile

## ========================================
## test locarna local
##

mkdir $outdir
calltest locarna-local $outdir $outfile -I'^#=GF CC Generated by LocARNA' locarna --sequ-local true $exdir/mouse.fa $exdir/human.fa -p 0.01 --max-diff-am 30 -q --stockholm $outfile

## ========================================
## test locarna normalized
##

mkdir $outdir
calltest locarna-normalized $outdir $outfile -I'^#=GF CC Generated by LocARNA' locarna --normalized 10 $exdir/mouse.fa $exdir/human.fa -p 0.01 --max-diff-am 30 -q --local-file-output --stockholm $outfile


## cleanup
rm -rf bin
rm -f lib


if $DIFFERENCES ; then
    echo "ERROR: test output and the expected results differ."
    exit -1
fi
