#!/usr/bin/env bash
# runCxxSmoke.sh — Phase 2.7 modern-C++ smoke harness.
#
# Builds each .cpp probe under tests/cxxSmoke/ through buildGno's recipe
# (clang++ -O2 + crt0Gno + libcGno + libcxxabi + omfEmit with
# ExpressLoad+cRELOCs), then launches the resulting OMF under GNO/ME in
# MAME via scripts/runInGno.sh and asserts the per-probe success
# markers in bank 2.
#
# Each probe stores the success sentinel 0x0099 at its dedicated marker
# slot; intermediate slots carry computed values that pin down which
# C++17 surface area was exercised.  See per-probe headers for the
# marker contract.
#
# Usage:
#   bash tests/cxxSmoke/runCxxSmoke.sh                # all five
#   bash tests/cxxSmoke/runCxxSmoke.sh rangeFor       # one
#   CXXSMOKE_FAIL_FAST=1 bash tests/cxxSmoke/runCxxSmoke.sh
#
# Exit status: 0 if every selected probe passes; 1 otherwise.  Each
# probe runs ~3 minutes under MAME (GNO boot + login + shell + program
# launch + marker poll), so the full sweep is ~15 minutes.

set -uo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"

# Probe table: name + space-separated "addr=hexval" pairs.  The last pair
# must always be the 0x0099 success sentinel; earlier pairs are computed
# values that anchor the check to the right surface area (so a partial
# regression — say the lambda fires but i32 capture is wrong — is caught
# at the data-pin rather than just the sentinel).
PROBES=(
    "rangeFor       0x025000=000F 0x025002=0099"
    "genericLambda  0x025000=2445 0x025002=0001 0x025004=0099"
    "variadicTpl    0x025000=0078 0x025002=0099"
    "structBind     0x025000=0007 0x025002=002A 0x025004=00DE 0x025006=00AD 0x025008=0099"
    "foldExpr       0x025000=000A 0x025002=000A 0x025004=0003 0x025006=0099"
)

# Optionally restrict to a single probe by basename.
SELECTED="${1:-}"

pass=0
fail=0
declare -a FAILED

for row in "${PROBES[@]}"; do
    set -- $row
    name="$1"; shift
    if [ -n "$SELECTED" ] && [ "$name" != "$SELECTED" ]; then
        continue
    fi

    echo ""
    echo "=== cxxSmoke: $name ==="

    if ! bash "$SCRIPT_DIR/build.sh" "$name"; then
        echo "[cxxSmoke FAIL] $name: build failed"
        fail=$((fail + 1))
        FAILED+=("$name (build)")
        if [ -n "${CXXSMOKE_FAIL_FAST:-}" ]; then
            break
        fi
        continue
    fi

    if bash "$ROOT/scripts/runInGno.sh" "$SCRIPT_DIR/$name.omf" --check "$@"; then
        echo "[cxxSmoke OK]   $name"
        pass=$((pass + 1))
    else
        echo "[cxxSmoke FAIL] $name: marker mismatch (see check output above)"
        fail=$((fail + 1))
        FAILED+=("$name (run)")
        if [ -n "${CXXSMOKE_FAIL_FAST:-}" ]; then
            break
        fi
    fi
done

echo ""
echo "=== cxxSmoke summary: $pass passed, $fail failed ==="
if [ "$fail" -gt 0 ]; then
    echo "failed probes:"
    for f in "${FAILED[@]}"; do
        echo "  - $f"
    done
    exit 1
fi
exit 0
