#!/bin/sh
#
# SPDX-FileCopyrightText: Peter Pentchev <roam@ringlet.net>
# SPDX-License-Identifier: BSD-2-Clause

set -e

ensure_empty()
{
	local filename="$1"

	if [ -s "$filename" ]; then
		echo "Did not expect anything in $filename" 1>&2
		cat -- "$filename"
		exit 1
	fi
}

check_output()
{
	local pattern="$1" filename="$2"

	if ! grep -Eqe "$pattern" -- "$filename"; then
		echo 'Unexpected output:' 1>&2
		cat -- "$filename" 1>&2
		exit 1
	fi
}

test_bad()
{
	local filename="$1" pattern="$2" prog_opts="$3"
	shift 3

	: > "$tempf"
	# shellcheck disable=SC2086  # prog_opts may be more than one argument
	if "$remrun" \
	    ${REMRUN_TEST_LOCAL_CKSUM_CMD:+-C "$REMRUN_TEST_LOCAL_CKSUM_CMD"} \
	    ${REMRUN_TEST_REMOTE_CKSUM_CMD:+-c "$REMRUN_TEST_REMOTE_CKSUM_CMD"} \
	    "$@" -- "$REMRUN_TEST_HOSTSPEC" "$filename" $prog_opts > "$tempf"; then
		echo 'Unexpected success; here is the output:' 1>&2
		cat -- "$tempf" 1>&2
		exit 1
	fi

	if [ -z "$pattern" ]; then
		ensure_empty "$tempf"
	else
		check_output "$pattern" "$tempf"
	fi
}

test_good()
{
	local filename="$1" pattern="$2" prog_opts="$3"
	shift 3

	: > "$tempf"
	# shellcheck disable=SC2086  # prog_opts may be more than one argument
	if ! "$remrun" \
	    ${REMRUN_TEST_LOCAL_CKSUM_CMD:+-C "$REMRUN_TEST_LOCAL_CKSUM_CMD"} \
	    ${REMRUN_TEST_REMOTE_CKSUM_CMD:+-c "$REMRUN_TEST_REMOTE_CKSUM_CMD"} \
	    "$@" -- "$REMRUN_TEST_HOSTSPEC" "$filename" $prog_opts > "$tempf"; then
		echo 'Unexpected failure; here is the output:' 1>&2
		cat -- "$tempf" 1>&2
		exit 1
	fi

	if [ -z "$pattern" ]; then
		ensure_empty "$tempf"
	else
		check_output "$pattern" "$tempf"
	fi
}

if [ "$#" -ne 1 ]; then
	echo 'Usage: run-test.sh /path/to/remrun' 1>&2
	exit 1
fi
remrun="$1"

if [ -z "$REMRUN_TEST_HOSTSPEC" ]; then
	echo 'No REMRUN_TEST_HOSTSPEC in the environment, skipping the test suite'
	exit 0
fi

datadir="$(dirname -- "$0")/test-data"
if [ ! -d "$datadir" ] || [ ! -f "$datadir/whoami.sh" ]; then
	echo "Invalid datadir detected: $datadir" 1>&2
	exit 1
fi

tempf="$(mktemp remrun-test.XXXXXX)"
# shellcheck disable=SC2064  # we *mean* to not expand it later
trap "rm -f -- '$tempf'" HUP INT EXIT QUIT TERM

printf '\n=== Fail with a nonexistent local file\n\n'
test_bad /nonexistent '' ''

printf '\n=== Do not run "whoami" on the remote host\n\n'
test_good "$datadir/whoami.sh" '^\./remrun\.[A-Za-z0-9._-]{6}$' '' -v -N

printf '\n=== Run "whoami" on the remote host\n\n'
test_good "$datadir/whoami.sh" '^[A-Za-z0-9._-]+$' ''

printf '\n=== Fail with mismatched local and remote checksum commands\n\n'
test_bad "$datadir/whoami.sh" '' '' -C cksum

printf '\n=== Fail again with mismatched local and remote checksum commands\n\n'
test_bad "$datadir/whoami.sh" '' '' -c cksum

printf '\n=== Use the same non-default checksum command on both sides\n\n'
test_good "$datadir/whoami.sh" '^[A-Za-z0-9._-]+$' '' -C cksum -c cksum

printf '\n=== Run "wc" on an empty stream, expected: 0 0 0 -\n\n'
test_good "$datadir/wc.sh" '^[[:space:]]*0[[:space:]]+0[[:space:]]+0$' '' -v

printf '\n=== Run "wc" on a non-empty stream\n\n'
test_good "$datadir/wc.sh" '^[[:space:]]*2[[:space:]]+9[[:space:]]+37$' '' -v -s < "$datadir/testfile.txt"

printf '\n=== Run a script that will fail\n\n'
test_bad "$datadir/fail.sh" 'I am failing' ''

printf '\n=== Run a script read from the standard input stream\n\n'
test_good - '^[A-Za-z0-9._-]+$' '' < "$datadir/whoami.sh"

printf '\n=== Do not allow -s and - together\n\n'
test_bad - '' '' -s < "$datadir/whoami.sh"

printf '\n=== Pass command-line arguments to the executed program\n\n'
test_good "$datadir/count.sh" '^12345$' 5

printf '\n=== Pass command-line arguments to the executed program 2\n\n'
test_good "$datadir/count.sh" '^0$' ''

printf '\n=== Pass command-line arguments to the executed program 3\n\n'
test_bad "$datadir/count.sh" '^Something weird' '5 6'

printf '\n=== All fine\n\n'
