#!/usr/bin/env bash
# Certify the self-hosted facts-roundtrip CLI against the current Racket oracle.
set -euo pipefail

source "$(dirname "$0")/_beagle-cold-authority"

ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "$ROOT"
source "$ROOT/bin/_beagle-racket"

CORPUS="$ROOT/bin/test/facts-roundtrip-selfhost/corpus.edn"
LAB="$ROOT/.lab/facts-roundtrip-certify"
MATERIALIZED="$LAB/corpus"
ORACLE="$LAB/oracle"
PORT="$LAB/port"
RT="$ROOT/beagle-lib/private/facts-roundtrip.rkt"

[[ "$#" -eq 0 ]] || {
  echo "usage: bin/beagle-certify-facts-roundtrip" >&2
  exit 2
}

rm -rf "${LAB:?}"
mkdir -p "$MATERIALIZED" "$ORACLE" "$PORT"

# Materialize inline fixtures under one stable repo-relative path. Path-backed
# cases use the current checked-in semantic fixtures.
bb -e '
  (require (quote [clojure.edn :as edn])
           (quote [clojure.java.io :as io]))
  (let [[manifest out-root] *command-line-args*]
    (doseq [{:keys [name ext source]} (edn/read-string (slurp manifest))
            :when source]
      (spit (io/file out-root (str name ext)) source)))' \
  "$CORPUS" "$MATERIALIZED"

mapfile -t CASES < <(
  bb -e '
    (require (quote [clojure.edn :as edn]))
    (doseq [{:keys [name ext source path]} (edn/read-string (slurp (first *command-line-args*)))]
      (println (str name "\t" (or path (str ".lab/facts-roundtrip-certify/corpus/" name ext)))))' \
    "$CORPUS"
)

capture_oracle() {
  local name="$1"
  local src="$2"
  "$RACKET" "$RT" --emit-edn "$src" > "$ORACLE/$name.emit"
  "$RACKET" "$RT" --render "$ORACLE/$name.emit" > "$ORACLE/$name.render"
}

# Pinned Racket startup dominates this gate. Run four independent cases per
# chunk and print each settled chunk so long certification runs stay observable.
ORACLE_CHUNK=4
for ((start=0; start<${#CASES[@]}; start+=ORACLE_CHUNK)); do
  pids=()
  stop=$((start + ORACLE_CHUNK))
  (( stop > ${#CASES[@]} )) && stop=${#CASES[@]}
  for ((idx=start; idx<stop; idx++)); do
    IFS=$'\t' read -r name src <<<"${CASES[$idx]}"
    capture_oracle "$name" "$src" &
    pids+=("$!")
  done
  chunk_fail=0
  for pid in "${pids[@]}"; do
    wait "$pid" || chunk_fail=1
  done
  [[ "$chunk_fail" -eq 0 ]] || {
    echo "facts-roundtrip certify: pinned-Racket oracle chunk failed" >&2
    exit 1
  }
  echo "oracle chunk: $stop/${#CASES[@]} cases captured"
done

run_port() {
  bin/beagle facts-roundtrip "$@"
}

fail=0
passed=0
for row in "${CASES[@]}"; do
  IFS=$'\t' read -r name src <<<"$row"
  if ! run_port --emit-edn "$src" > "$PORT/$name.emit"; then
    echo "FAIL $name: self-host emit exited nonzero" >&2
    echo "CERTIFY-CASE $name diff"
    fail=$((fail + 1))
    continue
  fi
  if ! run_port --render "$PORT/$name.emit" > "$PORT/$name.render"; then
    echo "FAIL $name: self-host render exited nonzero" >&2
    echo "CERTIFY-CASE $name diff"
    fail=$((fail + 1))
    continue
  fi

  if cmp -s "$ORACLE/$name.emit" "$PORT/$name.emit" &&
     cmp -s "$ORACLE/$name.render" "$PORT/$name.render"; then
    echo "CERTIFY-CASE $name ok"
    passed=$((passed + 1))
  else
    echo "FAIL $name: byte divergence (inspect $LAB)" >&2
    echo "CERTIFY-CASE $name diff"
    fail=$((fail + 1))
  fi
  settled=$((passed + fail))
  if (( settled % 4 == 0 || settled == ${#CASES[@]} )); then
    echo "port chunk: $settled/${#CASES[@]} cases compared"
  fi
done

echo "facts-roundtrip certify: $passed/${#CASES[@]} current cases byte-identical, $fail failed"
[[ "$fail" -eq 0 ]]
