#!/bin/sh
# test/run — driver for `make test`. Plan 9 rc-flavoured but plain sh.
#
# Walks test/wcc/<NNN>_<name>.c → out/bin/test_<name> binary, fans out
# across $JOBS (default $(nproc)) workers via xargs -P. Each worker
# writes its status to a per-job file; the collector enumerates them in
# lexicographic order so output stays deterministic across runs even
# though execution interleaves. Exit non-zero if any worker failed.

BIN=${BIN:-out/bin}
WW=${WW:-$BIN/ww}

# Worker mode: invoked once per test by xargs. Argv: --one <prefix> <test.c>.
# Writes <prefix>.status; touches <prefix>.fail on a non-zero binary exit.
if [ "$1" = "--one" ]; then
	prefix=$2
	t=$3
	name=${t##*/}
	name=${name%.c}
	short=${name#[0-9][0-9][0-9]_}
	bin=$BIN/test_$short
	if [ ! -x "$bin" ]; then
		printf 'SKIP %s (no binary %s)\n' "$name" "$bin" > "$prefix.status"
		exit 0
	fi
	if "$bin" > "$prefix.out" 2> "$prefix.err"; then
		printf 'ok   %s\n' "$name" > "$prefix.status"
	else
		rc=$?
		{
			printf 'FAIL %s (rc=%d)\n' "$name" "$rc"
			echo '--- stdout ---'
			cat "$prefix.out"
			echo '--- stderr ---'
			cat "$prefix.err"
		} > "$prefix.status"
		: > "$prefix.fail"
	fi
	exit 0
fi

set -e

RESULTS=$(mktemp -d "${TMPDIR:-/tmp}/wwtest.XXXXXX")
trap 'rm -rf "$RESULTS"' EXIT

JOBS=${JOBS:-$(nproc 2>/dev/null || echo 4)}

# Emit (prefix, testpath) pairs NUL-separated. The prefix carries the
# test's <NNN>_<name> stem so the collector iterates in lexical order,
# yielding deterministic output even though workers interleave.
for t in test/wcc/*.c; do
	[ -f "$t" ] || continue
	name=${t##*/}; name=${name%.c}
	printf '%s/%s\0%s\0' "$RESULTS" "$name" "$t"
done | xargs -0 -n2 -P "$JOBS" "$0" --one || true

fail=0
ran=0
for s in "$RESULTS"/*.status; do
	[ -f "$s" ] || continue
	cat "$s"
	ran=$((ran + 1))
	prefix=${s%.status}
	[ -f "$prefix.fail" ] && fail=$((fail + 1))
done

# ---- ww source-level tests ----------------------------------------------
if [ -d test/lang ]; then
	for f in test/lang/*/*.ww; do
		[ -f "$f" ] || continue
		echo "skip $f (ww run not online yet)"
	done
fi

if [ $ran -eq 0 ]; then
	echo "no tests were run"
	exit 1
fi
if [ $fail -gt 0 ]; then
	echo "$fail test(s) failed"
	exit 1
fi
echo "all $ran tests passed"
