#!/bin/sh
set -eu

# pt2-clone has no command line option for rendering a module to WAV (there
# is no "-d").  Rendering is only available through the GUI, so start a
# private X server and drive the MOD2WAV dialog with xdotool.  Audio output
# uses SDL's dummy driver, so no sound card is required.
#
# AI-assisted script, reviewed and tested by snd@debian.org

if [ "${PT2_TEST_IN_XVFB:-0}" != 1 ]; then
	if [ "$(python3 -c 'import sys; print(sys.byteorder)')" = big ]; then
		echo "SKIP: pt2-clone writes WAV headers in native endianness, which breaks them on big-endian" >&2
		exit 77
	fi

	export PT2_TEST_IN_XVFB=1
	exec xvfb-run -a -s "-screen 0 640x480x24" "$0" "$@"
fi

SELF_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
WORKDIR=$(mktemp -d)
PT2_PID=

cleanup()
{
	if [ -n "${PT2_PID:-}" ]; then
		kill "$PT2_PID" 2>/dev/null || true
		wait "$PT2_PID" 2>/dev/null || true
	fi
	rm -rf "$WORKDIR"
}
trap cleanup EXIT HUP INT TERM

export HOME="$WORKDIR/home"
mkdir -p "$HOME"

# A real X11 driver is needed (SDL's "dummy" video driver has no renderer).
# The sound card is not needed, so keep SDL's dummy audio driver.
export SDL_AUDIODRIVER=dummy
unset SDL_VIDEODRIVER AUDIODRIVER

MOD="$WORKDIR/TESTMOD.mod"
python3 "$SELF_DIR/pt2_test_utils.py" make-mod "$MOD"

cd "$HOME"

# The installed binary is called "protracker" (see debian/install).
protracker "$MOD" >"$WORKDIR/protracker.out" 2>&1 &
PT2_PID=$!

show_log()
{
	echo "--- protracker output ---" >&2
	cat "$WORKDIR/protracker.out" >&2 || true
	echo "-------------------------" >&2
}

# Wait until the module was parsed and its name appears in the window title.
WID=
i=0
while [ "$i" -lt 300 ]; do
	if ! kill -0 "$PT2_PID" 2>/dev/null; then
		echo "FAIL: protracker exited during startup" >&2
		show_log
		exit 1
	fi

	WID=$(xdotool search --name 'TESTMOD' 2>/dev/null | head -n 1 || true)
	if [ -n "$WID" ]; then
		break
	fi

	sleep 0.1
	i=$((i + 1))
done

if [ -z "$WID" ]; then
	echo "FAIL: no window with the loaded module name was found" >&2
	show_log
	exit 1
fi

TITLE=$(xdotool getwindowname "$WID")
echo "Window title: $TITLE"

# Determine the window scale so the clicks below work for any fit setting.
eval "$(xdotool getwindowgeometry --shell "$WID")"
SCALE_X=$((WIDTH / 320))
SCALE_Y=$((HEIGHT / 255))
[ "$SCALE_X" -ge 1 ] || SCALE_X=1
[ "$SCALE_Y" -ge 1 ] || SCALE_Y=1

sleep 1

# "MOD 2 WAV" button on the top screen (x=244..305, y=0..10).
xdotool mousemove --window "$WID" $((274 * SCALE_X)) $((5 * SCALE_Y))
sleep 0.2
xdotool click 1
sleep 1

# "RENDER TO WAV" button in the dialog (x=142..246, y=84..94).
xdotool mousemove --window "$WID" $((194 * SCALE_X)) $((89 * SCALE_Y))
sleep 0.2
xdotool click 1

# Wait for the WAV file to be written and completely flushed.
WAV=
DONE=0
i=0
while [ "$i" -lt 300 ]; do
	if ! kill -0 "$PT2_PID" 2>/dev/null; then
		echo "FAIL: protracker exited while rendering" >&2
		show_log
		exit 1
	fi

	WAV=$(find "$HOME" -maxdepth 3 -type f -name 'testmod.wav' -print -quit 2>/dev/null || true)
	if [ -n "$WAV" ]; then
		SIZE1=$(stat -c %s "$WAV")
		sleep 0.5
		SIZE2=$(stat -c %s "$WAV")
		if [ "$SIZE1" -gt 44 ] && [ "$SIZE1" = "$SIZE2" ]; then
			DONE=1
			break
		fi
	fi

	sleep 0.1
	i=$((i + 1))
done

if [ "$DONE" -ne 1 ]; then
	echo "FAIL: no complete WAV file was rendered" >&2
	find "$HOME" -maxdepth 3 -type f >&2 || true
	show_log
	exit 1
fi

echo "Rendered file: $WAV ($(stat -c %s "$WAV") bytes)"
python3 "$SELF_DIR/pt2_test_utils.py" check-wav "$WAV"

# Ask the application to quit, then fall back to SIGTERM if it did not.
xdotool windowclose "$WID" 2>/dev/null || true
i=0
while [ "$i" -lt 50 ]; do
	kill -0 "$PT2_PID" 2>/dev/null || break
	sleep 0.1
	i=$((i + 1))
done
if kill -0 "$PT2_PID" 2>/dev/null; then
	kill "$PT2_PID" 2>/dev/null || true
fi
wait "$PT2_PID" 2>/dev/null || true
PT2_PID=

echo "PASS: protracker loaded the module, rendered it headlessly and produced valid audio."
