# This file is in the public domain.
#
# Inlined into test scripts that need a live GNU Taler system.  Defines
# setup(), which wraps `taler-unified-setup.sh': it launches the services,
# waits until they report READY, and installs an exit handler that stops
# them again.  Pass setup() the arguments for taler-unified-setup.sh.
#
# This is the same wrapper the merchant and anastasis test suites use.
# Keep it in step with them rather than improving it here.

set -eu

# The Taler services write into TALER_TEST_HOME (see test_paywall.conf);
# an XDG variable inherited from the caller would send parts of them
# somewhere else and the run would use a mix of the two.
unset XDG_DATA_HOME
unset XDG_CONFIG_HOME


# Exit with the meson/automake "skip" status.  A missing component is an
# environment problem, not a regression, and must not fail the suite.
function exit_skip() {
    echo "SKIPPING: $*" >&2
    exit 77
}

function exit_fail() {
    echo "$@" >&2
    exit 1
}

# Cleanup to run whenever we exit
function exit_cleanup()
{
    if [ ! -z ${SETUP_PID+x} ]
    then
        echo "Killing taler-unified-setup ($SETUP_PID)" >&2
        kill -TERM "$SETUP_PID" 2> /dev/null || true
        wait "$SETUP_PID" 2> /dev/null || true
    fi
}

# Install cleanup handler (except for kill -9)
trap exit_cleanup EXIT

function setup()
{
    echo "Starting test system ..." >&2
    # Create a named pipe in a temp directory we own.
    FIFO_DIR=$(mktemp -p "${TMPDIR:-/tmp}" -d fifo-XXXXXX)
    FIFO_OUT="$FIFO_DIR/out"
    mkfifo "$FIFO_OUT"
    # Open pipe as FD 3 (RW) and FD 4 (RO)
    exec 3<> "$FIFO_OUT" 4< "$FIFO_OUT"
    rm -rf "$FIFO_DIR"
    # We require '-W' for our termination logic to work.
    taler-unified-setup.sh -W "$@" >&3 &
    SETUP_PID=$!
    # Close FD3
    exec 3>&-
    # Pass the setup's output through until it announces READY:.  Note that
    # reaching end-of-pipe is NOT success: that is what happens when
    # taler-unified-setup.sh dies during startup, and continuing then makes
    # the test fail much later against a system that was never brought up,
    # hiding the actual error.  So insist on having seen the marker.
    SETUP_READY=0
    while IFS= read -r line <&4
    do
        printf '%s\n' "$line"
        case "$line" in
            *READY:*)
                SETUP_READY=1
                break
                ;;
        esac
    done
    # Close FD4
    exec 4>&-
    if [ "1" != "$SETUP_READY" ]
    then
        wait "$SETUP_PID" || SETUP_STATUS=$?
        unset SETUP_PID
        if [ "${SETUP_STATUS:-1}" = "77" ]
        then
            exit_skip "taler-unified-setup.sh could not launch the test system"
        fi
        exit_fail "taler-unified-setup.sh died with status ${SETUP_STATUS:-?} before the test system was ready"
    fi
    echo "Test system ready" >&2
}
