#!/usr/bin/env bash
# Tcl-on-SX conformance runner — epoch protocol to sx_server.exe
# Usage: lib/tcl/conformance.sh [file.tcl ...]
#   Defaults to lib/tcl/tests/programs/*.tcl
set -uo pipefail
cd "$(git rev-parse --show-toplevel)"

SX_SERVER="${SX_SERVER:-hosts/ocaml/_build/default/bin/sx_server.exe}"
if [ ! -x "$SX_SERVER" ]; then
  SX_SERVER="/root/rose-ash/hosts/ocaml/_build/default/bin/sx_server.exe"
fi
if [ ! -x "$SX_SERVER" ]; then echo "ERROR: sx_server.exe not found"; exit 1; fi

SCOREBOARD_JSON="${SCOREBOARD_JSON:-lib/tcl/scoreboard.json}"
SCOREBOARD_MD="${SCOREBOARD_MD:-lib/tcl/scoreboard.md}"

# Collect tcl files
if [ "$#" -gt 0 ]; then
  TCL_FILES=("$@")
else
  TCL_FILES=(lib/tcl/tests/programs/*.tcl)
fi

# Generate a helper .sx file that defines the Tcl source as an SX string variable.
# We escape the source for SX string literals: backslashes → \\, quotes → \", newlines → \n.
# This is safe in a (define ...) context — no double-parsing like (eval "...") would cause.
write_sx_helper() {
  local tcl_file="$1"
  local helper_file="$2"
  python3 << PYEOF
src = open('${tcl_file}').read()
escaped = src.replace('\\\\', '\\\\\\\\').replace('"', '\\\\"').replace('\\n', '\\\\n')
with open('${helper_file}', 'w') as f:
    f.write(f'(define __tcl-src "{escaped}")\\n')
    f.write('(define __tcl-result (get (tcl-eval-string (make-default-tcl-interp) __tcl-src) :result))\\n')
PYEOF
}

total=0
passed=0
failed=0
programs_json=""
md_rows=""

for tcl_file in "${TCL_FILES[@]}"; do
  basename_noext=$(basename "$tcl_file" .tcl)
  total=$((total + 1))

  # Read expected value from first-line comment "# expected: VALUE"
  expected=$(head -1 "$tcl_file" | sed -n 's/^# expected: *//p')
  if [ -z "$expected" ]; then
    echo "WARN: no '# expected:' annotation in $tcl_file — skipping"
    continue
  fi

  tmpfile=$(mktemp)
  helper=$(mktemp --suffix=.sx)
  trap "rm -f $tmpfile $helper" EXIT

  # Write helper .sx with Tcl source embedded as SX string
  write_sx_helper "$tcl_file" "$helper"

  # Build epoch input using quoted heredoc for static parts; helper path via variable
  cat > "$tmpfile" << EPOCHS
(epoch 1)
(load "lib/guest/lex.sx")
(load "lib/guest/prefix.sx")
(load "lib/tcl/tokenizer.sx")
(epoch 2)
(load "lib/tcl/parser.sx")
(epoch 3)
(load "lib/guest/reflective/env.sx")
(load "lib/tcl/runtime.sx")
(epoch 4)
(load "$helper")
(epoch 5)
(eval "__tcl-result")
(epoch 6)
EPOCHS

  output=$(timeout 30 "$SX_SERVER" < "$tmpfile" 2>&1)
  got=$(echo "$output" | grep -A1 "^(ok-len 5 " | tail -1 | tr -d '"')

  if [ "$got" = "$expected" ]; then
    status="PASS"
    passed=$((passed + 1))
    echo "PASS  $basename_noext  (expected: $expected, got: $got)"
  else
    status="FAIL"
    failed=$((failed + 1))
    echo "FAIL  $basename_noext  (expected: $expected, got: ${got:-<empty>})"
    if [ -n "${VERBOSE:-}" ]; then
      echo "--- server output ---"
      echo "$output"
      echo "--- helper.sx ---"
      cat "$helper"
    fi
  fi

  # Accumulate JSON fragment (escape for JSON)
  got_json=$(printf '%s' "$got" | python3 -c "import sys,json; sys.stdout.write(json.dumps(sys.stdin.read()))" | tr -d '"')
  exp_json=$(printf '%s' "$expected" | python3 -c "import sys,json; sys.stdout.write(json.dumps(sys.stdin.read()))" | tr -d '"')

  if [ -n "$programs_json" ]; then
    programs_json="${programs_json},"
  fi
  programs_json="${programs_json}
    \"${basename_noext}\": {\"status\": \"${status}\", \"expected\": \"${exp_json}\", \"got\": \"${got_json}\"}"

  # Accumulate Markdown row
  if [ "$status" = "PASS" ]; then
    icon="✓ PASS"
  else
    icon="✗ FAIL"
  fi
  md_rows="${md_rows}| ${basename_noext} | ${icon} | ${expected} | ${got} |
"
done

# Write scoreboard.json
cat > "$SCOREBOARD_JSON" << JSON
{
  "total": ${total},
  "passed": ${passed},
  "failed": ${failed},
  "programs": {${programs_json}
  }
}
JSON

# Write scoreboard.md
cat > "$SCOREBOARD_MD" << MD
# Tcl-on-SX Conformance Scoreboard

| Program | Status | Expected | Got |
|---|---|---|---|
${md_rows}
**${passed}/${total} passing**
MD

echo ""
echo "Scoreboard: ${passed}/${total} passing"
echo "Written: $SCOREBOARD_JSON, $SCOREBOARD_MD"

if [ "$failed" -gt 0 ]; then
  exit 1
fi
exit 0
