#!/usr/bin/env bash

#Just a couple helpers
function myhelp {
    echo "usage: ${0} [-h] [-k] [-v] [-t TEMPFILENAME] [-f FILE] [ENVVAR=VALUE ...]"
}

function verbose {
    if [ -n "${_VERBOSE}" ];then
	echo $@
    fi
}

#Commandline processing.
while getopts ":f:vhkt:" opt; do
    case ${opt} in
	f) _TESTFILE=${OPTARG} ;;
	v) _VERBOSE="TRUE" ;;
	k) _KEEPTEMPS="TRUE" ;;
	t) CMDTMP=${OPTARG}
	    _KEEPTEMPS="TRUE" 
	    ;;
	h) myhelp; exit 0 ;;
	?) echo "Unsupported argument -${OPTARG}"
	    _ERROR="KILL ME!"
	    ;;
    esac
done
#check for errors
if [ -n "${_ERROR}" ]; then
    myhelp
    exit 2
fi
#move commandline over
shift $(( OPTIND-1 ))

#All of the remaining commandline options are exported 
#into the users environment.
for opt in ${@}; do
    export ${opt}
    verbose "Exported: ${opt}"
done

if [ -z "${_TESTFILE}" ];then
    for _FF in testfile Testfile TESTFILE; do
	if [ -e ${_FF} ];then
	    _TESTFILE=${_FF}
	    break
	fi
    done
fi
if [ ! -e ${_TESTFILE} ];then
    echo "ERROR: Testfile not found:  Searched for"
    echo "       'testfile', 'Testfile', 'TESTFILE'"
    echo "       Specify a different file with -f"
fi
verbose "TESTFILE found: ${_TESTFILE}"

function setenv {
    #Set an environment variable if it isn't in the environment
    #already.
    local WHAT=$1
    local VAL=$2
    eval "${WHAT}=\${${WHAT}-${VAL}}"
}

_UNITTESTDIR=${0%/*}
#if OPENGGCMDIR is set, use that, otherwise, use ${_UNITTESTDIR}/..
OPENGGCMDIR=${OPENGGCMDIR-${_UNITTESTDIR}/..}
_OPENGGCMDIR=${OPENGGCMDIR}

function testexit {
    if [ $1 -ne 0 ];then
	cleanup
	echo $2 1>&2
	exit $1
    fi
}

function write {
    echo "${1}" >> ${_TMPFILE}
}

function init {
    local LTMP=tmp.${RANDOM}.F
    if [ -n "${CMDTMP}" ];then
	rm -rf ${CMDTMP} 2>/dev/null
    fi

    _TMPFILE=${CMDTMP-${LTMP}}  #${FC-gfortran}  #default compiler is gfortran
    if [ -e ${_TMPFILE} ]; then
	echo "ERROR: _TMPFILE ${_TMPFILE} already exists!" 1>&2
	exit 1
    fi
    touch ${_TMPFILE}
}

function cleanup {
    if [ -z "${_KEEPTEMPS}" ]; then
	rm -rf ${_TMPFILE} 2>&1
    fi
}


function include {
    #Simply includes the files
    local _cmd="cat $@ >> ${_TMPFILE}"
    verbose "executing:" ${_cmd}
    eval ${_cmd}
    testexit $? "ERROR: include failed with status $?"
}

function extract {
    #Called as "extract this from that"
    # "this" can be a subroutine, cliche, special text guared by c.test blah...
    # or comma separated list
    # of subroutines/cliches.
    local _A=( ${@} )
    local _FROM=${_A[1]}
    if [ "${_FROM}" != "from" ]; then
	echo "ERROR: Argument 2 of 'extract' must be 'from'" 1>&2
	cleanup
	exit 1
    fi
    local _REST=${_A[@]:2:${#}}
    local _cmd="python ${_OPENGGCMDIR}/bin/script.testextract -t ${1} ${_REST} >> ${_TMPFILE}"
    verbose "executing:" ${_cmd}
    eval ${_cmd}
    testexit $? "ERROR: extract failed with status $?"
}

function sed_extract {
    #Called as "sed_extract start stop from file"
    #incoporate text from regular expresson start to regular expression stop
    local _start=$1
    local _stop=$2
    local _FROM=$3
    local _WHENCE=$4
    if [ "${_FROM}" != "from" ]; then
	echo "ERROR: Argument 3 of 'sed_extract' must be 'from'" 1>&2
	cleanup
	exit 1
    fi
    local _cmd="sed -n '/${_start}/,/${_stop}/p' ${_WHENCE} >> ${_TMPFILE}"
    verbose "executing:" ${_cmd}
    eval ${_cmd}
    testexit $? "ERROR: sed_extract failed with status $?"
}
    

function fpreprocess {
    local NEW_TEMP="${_TMPFILE}.new_temp"
    local LFPPN=${FPPN-fppn -c -q --}
    local _cmd="${LFPPN} ${_TMPFILE} > ${NEW_TEMP} && mv ${NEW_TEMP} ${_TMPFILE} "
    verbose "executing:" ${_cmd}
    eval ${_cmd}
    local EC=$?
    rm -rf ${NEW_TEMP} 2>/dev/null
    testexit ${EC} "ERROR: Failed to preprocess with ${LFPPN}"
    
}

function dump {
    local WHERE=$1
    if [ -n "${WHERE}" ];then
	cat ${_TMPFILE} > ${WHERE}
    else
	cat ${_TMPFILE}
    fi
}

function fcompile {
    #Generates an executable "ftest, or whatever the user supplies..."
    #Note that you could make it just compile (not link) with
    #fcompile "ftest.o -c"
    local OUTPUT=${1-ftest}
    local LFC=${FC-gfortran}  #default compiler is gfortran
    local LFCFLAGS=${FCFLAGS--O2 -g -Wall -Wno-unused} #default FCFLAGS are -O2 -g -Wall
    local _cmd="${LFC} ${LFCFLAGS} -o ${OUTPUT} ${_TMPFILE}"
    verbose "executing:" ${_cmd}
    eval "${_cmd}"
}

function run {
    eval $@
}

init  #Initialize (create temporary file)
source ${_TESTFILE}
cleanup
