#!/bin/sh
#
# Copyright (c) 2021, 2022  Peter Pentchev <roam@ringlet.net>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.

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

{{#each tests }}
printf '\n=== {{this.title}}\n\n'
test_{{#if this.success}}good{{else}}bad{{/if}} {{datafile this.filename}} '{{this.output_template}}' {{shell_quote (shell_join this.program_options)}}{{#if this.remrun_options}} {{shell_join this.remrun_options}}{{/if}}{{#if this.stdin_filename}} < {{datafile this.stdin_filename}}{{/if}}

{{/each}}
printf '\n=== All fine\n\n'
