#!/bin/sh

# shellcheck disable=SC1091
. ././common-setup.sh

# Use absolute path so tests that change working directory still use 
# scripts from parent directory.  Note that using $PWD seems to fail
# here under Gitlab's CI environment.
PATH=$(realpath ..):$(realpath .):${PATH}

experimental=""
serial=""
mode=diffing
log=""
logto="echo"
while getopts a:bhil:noqsx opt
do
    case $opt in
	a) arg=$OPTARG;;
	b) mode=build;;
	i) interactive="set flag interactive" ;;
	l) log="log $OPTARG" ;;
	n) mode=errs;;
	o) mode=view;;
	q) logto=":";;
	s) serial="set flag serial";;
	x) experimental="set flag experimental";;
	*) cat <<EOF
singletest - run a single regression test

The REPOSURGEON environment variable can be used to substitute in a
different implementation.

With -a, pass an argument for the script

With -b. regenerate the corresponding check file

With -h, display this option summary.

With -i, set the interactive flag.

With -l, set log bits (only with -o)

With -n, pass out stderr but consume stdout.

With -o, dump the test output rather than diffing against the checkfile

With -q, suppress logging of the test legend to stderr

With -s, set the serial flag to disable parallelism

With -x, set the experimental flag.

Otherwise, run the test and emit a report in TAP format.
If the test generated a nonempty diff it is displayed as
a detail message. QUIET=1 suppresses diff output, shipping
only the TAP not-ok line.

If the test file's descrioption line contains the token TODO,
the output TAP line will have a TODO directive.  If it contains
the token SKIP, the test will be skipped and an ok line with
a SKIP directive emitted.
EOF
	   exit 0;;
    esac
done
# shellcheck disable=SC2004
shift $(($OPTIND - 1))

trap 'rm -f /tmp/tapdiff$$' EXIT HUP INT QUIT TERM

# shellcheck disable=SC2068
for x in $@;
do
    what=$(echo "${x}" | sed -e '/-FAILED/s///' -e '/.tst/s///')

    if [ -f "${what}.tst" ]
    then
	tst="${what}.tst"
	chk="${what}.chk"
    elif [ -f "${what}.tst-FAIL" ]
    then
	tst="${what}.tst-FAIL"
	chk="${what}.chk"
	echo "Expect a diff"
    elif [ -z "${what}" ]
    then
	exec "$0" -h
	exit 1
    else
	echo "No script matching ${what} found"
	exit 1
    fi

    legend=$(grep '^##' "${tst}" 2>/dev/null || echo "## (no description)")
    directive=""
    if grep ' ##.*TODO' "${tst}" >/dev/null
    then
	directive='# TODO '
    elif grep ' ##.*SKIP' "${tst}" >/dev/null
    then
	echo "ok - $ SKIP ${tst}: ${legend}"
	exit 0
    fi

    # Take input from /dev/null so we won't have a screenwidth dependency.
    case $mode in
    build) "${logto}" "${legend}" >&2; ${REPOSURGEON:-reposurgeon} "set flag serial" "$experimental" "$interactive" "do ${tst} ${arg}" </dev/null >"${chk}" 2>&1 ;;
    view)  "${logto}" "${legend}" >&2; ${REPOSURGEON:-reposurgeon} "$log" "$serial" "$experimental" "$interactive" "do ${tst} ${arg}" </dev/null 2>&1 ;;
    errs)  "${logto}" "${legend}" >&2; ${REPOSURGEON:-reposurgeon} "$serial" "$experimental" "$interactive" "do ${tst}" </dev/null >/dev/null ;;
    *)     legend=$(echo "${legend}" | sed -e 's/## //')
	   cat </dev/null >/tmp/tapdiff$$
	   if ${REPOSURGEON:-reposurgeon} "$serial" "$experimental" "do ${tst} ${arg}" 2>&1 | diff -u "${chk}" -  >/tmp/tapdiff$$ 2>&1 && [ ! -s /tmp/tapdiff$$ ]
	   then
	       echo "ok - ${directive}${legend}"
	       exit 0
	   else
	       echo "not ok - ${directive}${x}: ${legend}"
	       if [ ! "${QUIET}" = 1 ]
	       then
		   echo "  --- |"
		   sed </tmp/tapdiff$$ -e 's/^/  /'
		   echo "  ..."
	       fi
	       exit 1
	   fi	   
	   ;;
    esac
done

# Return exit status of the last command to run.
# In particular, if the last command was a diff,
# this will return 0 for empty and 1 for nonempty.
# Otherwise you'll typically get the exit status
# of reposurgeon. 
exit $?
