#!/bin/bash

. "$TF_DIR/include/common.sh"

# 1. exec: [test] -> [result]
# 2. eval:           [result] == [oracle]

tf_testflt() {
    #
    # Run a simple test for a unix filter
    #
    #     tf_testflt -n foo [-i foo.stdin] \
    #                [-O ffoo.stdout] [-E ffoo.stderr] [-S 3] \
    #                cmd arg...
    #
    # Will drop *result/NAME.stdout* and *result/NAME.stderr* (intentionally
    # not cleaning up).
    #

    # defaults
    #
    local t_in="/dev/null"      # test: stdin
    local t_name=""             # test: name
                                # command is "$@" after arg parsing
    local t_es="0"              # final test exit status
    local o_out="/dev/null"     # oracle: stdout
    local o_err="/dev/null"     # oracle: stderr
    local o_es="0"              # oralce: exit status
    local r_out r_err r_es      # result: ^ ^ ^ those 3

    # get args
    #
    local orig_args="$0 $*"
    tf_debug "orig_args=$orig_args"
    local arg_err=false
    while true; do case "$1" in
        -i) t_in="$2";          shift 2 || { arg_err=true; break; } ;;
        -n) t_name="$2";        shift 2 || { arg_err=true; break; } ;;
        -O) o_out="$2";         shift 2 || { arg_err=true; break; } ;;
        -E) o_err="$2";         shift 2 || { arg_err=true; break; } ;;
        -S) o_es="$2";          shift 2 || { arg_err=true; break; } ;;
        --)                     shift; break ;;
        "")                            break ;;
        -*) tf_warn "wrong testcli arg: $1"; return $TF_ES_BAILOUT ;;
        *)                             break ;;
    esac done
    $arg_err && { tf_warn "error parsing arguments: $orig_args"; return $TF_ES_BAILOUT; }
    tf_debug "t_in='$t_in'"
    tf_debug "t_name='$t_name'"
    tf_debug "o_out='$o_out'"
    tf_debug "o_err='$o_err'"
    tf_debug "o_es='$o_es'"
    tf_debug "test command: $*"
    test "$t_in" = "-" && t_in=/dev/stdin   # works better for check below
    test -z "$t_name"  && { tf_warn "missing test name"             ; return $TF_ES_BAILOUT; }
    test -z "$1"       && { tf_warn "missing test command"          ; return $TF_ES_BAILOUT; }
    test -r "$t_in"    || { tf_warn "missing input file: $t_in"     ; return $TF_ES_BAILOUT; }
    test -e "$o_out"   || { tf_warn "missing oracle stdout: $o_out" ; return $TF_ES_BAILOUT; }
    test -e "$o_err"   || { tf_warn "missing oracle stderr: $o_err" ; return $TF_ES_BAILOUT; }
    test "$o_es" -ge 0 || { tf_warn "invalid oracle status: $o_es"  ; return $TF_ES_BAILOUT; }

    # prepare
    #
    mkdir -p result
    r_out="result/$t_name.stdout"
    r_err="result/$t_name.stderr"
    tf_debug "r_out='$r_out'"
    tf_debug "r_err='$r_err'"
    touch "$r_out" || { tf_warn "cannot create tmp file: $r_out" ; return $TF_ES_BAILOUT; }
    touch "$r_err" || { tf_warn "cannot create tmp file: $r_err" ; return $TF_ES_PANIC; }

    # run
    #
    ( <"$t_in" eval "$@" >"$r_out" 2>"$r_err" ); r_es=$?
    tf_debug "r_es='$r_es'"

    # eval/report/exit
    #
    test $r_es = $o_es || { tf_warn "bad exit status: $r_es (need $o_es)" ; t_es=$TF_ES_FAIL; }
    diff -u "$o_err" "$r_err" || t_es=$TF_ES_FAIL
    diff -u "$o_out" "$r_out" || t_es=$TF_ES_FAIL
    return $t_es
}