#!/bin/bash
set -e

program="$1"; shift

scripts=()
while true; do
    case "$1" in
	--) shift; break;;
	-*) echo >&2 "unknown option $1"; exit 127;;
	*) scripts+=("$1"); shift;;
    esac
done
cmd=("$@")

count_file="$DGIT_TEST_TMP/flaky-$program.count"

if [ -f "$count_file" ]; then
    read <"$count_file" count
else
    count=0
fi
msgprefix="[$program $count]"
echo >"$count_file" 99999999

report () {
    echo >&2 "$msgprefix: $2"
    save-count
    exit $1
}

crash () {
    echo >&2 "$msgprefix: crashing: $*"
    exit 127
}

save-count () {
    count=$(( $count + 1 ))
    echo >"$count_file" $count
}

#----- subroutines for use by argument script fragments -----

just-fail () {
    report 127 "just failing"
}

run-expect-failure () {
    echo >&2 "running (expecting failure)"
    set +e
    "${cmd[@]}"
    rc=$?
    set -e
    test $rc != 0
    report $rc "failed as expected"
}

run-expect-success-but-report-failure () {
    "${cmd[@]}"
    report 127 "actually succeeded, but reporting failure"
}

run-expect-success () {
    "${cmd[@]}"
    report 0 "succeeded"
}

#----- run the relevant script -----

if [ $count -ge ${#scripts[*]} ]; then
    crash "too many invocations ($count) or previous crash"
fi

eval "${scripts[$count]}"

crash "fragment $count didn't call report"
