#!/usr/bin/env bash
# W0 (#248) field acceptance — doyle, 2026-09-06. Isolated SPT_HOME, isolated docs port
# (the perch daemon owns 5474 on this box), identity trio scrubbed. Every check prints
# PASS/FAIL with the observed value; exit = number of FAILs. Run from the gate worktree
# after the pool is warm: bash .spt/field-w0.sh [node-label] [port]
set -u
NODE="${1:-hfenduleam}"; PORT="${2:-5480}"
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
SPT="$ROOT/target/debug/spt.exe"
[ -x "$SPT" ] || { echo "FAIL: no built spt at $SPT"; exit 1; }
HOME_DIR="$(mktemp -d "${TMPDIR:-/tmp}/w0field.XXXXXX")"
SRC="$HOME_DIR/srcs"; mkdir -p "$SRC/one" "$SRC/two" "$SRC/three" "$SRC/mock"
export SPT_HOME="$(cygpath -w "$HOME_DIR" 2>/dev/null || echo "$HOME_DIR")"
export SPT_DOCS_PORT="$PORT"
unset OWL_SESSION_ID SPT_AGENT_ID SPT_ENDPOINT_ID SPT_SESSION_NAME SPT_ADAPTER SPT_HOST_PID SPT_INJECT_VERIFY_ECHO
fails=0
check() { # name expected actual
  if [ "$2" = "$3" ]; then echo "PASS $1: $3"; else echo "FAIL $1: expected [$2] got [$3]"; fails=$((fails+1)); fi
}
code() { curl -s -o /dev/null -w '%{http_code}' "$@"; }
B="http://127.0.0.1:$PORT"
W() { cygpath -w "$1" 2>/dev/null || echo "$1"; }

echo "one" > "$SRC/one/report.md"; echo "two" > "$SRC/two/report.md"; echo "three" > "$SRC/three/report.md"
cat > "$SRC/mock/manifest.toml" <<'EOF'
[adapter]
name = "mock"
kind = "harness"
version = "1.0.0"
min_spt_core_version = "0.1.0"
hostable_types = ["LiveAgent"]
web_short_path = "reports"
EOF

"$SPT" node start >"$HOME_DIR/start.log" 2>&1; check daemon_start 0 $?
sleep 2
check root_302 302 "$(code "$B/")"
check root_location "/$NODE/" "$(curl -s -o /dev/null -w '%{redirect_url}' "$B/" | sed -E 's#^https?://[^/]+##')"
check index_200 200 "$(code "$B/$NODE/")"
check index_json_200 200 "$(code "$B/$NODE/?json")"
check facet_f_404 404 "$(code "$B/$NODE/f/")"
check facet_f_body "FACET_NOT_FOUND: f" "$(curl -s "$B/$NODE/f/" | tr -d '\r\n')"
check f_miss_is_registry_miss "NOT_FOUND: served resource nope" "$(curl -s "$B/$NODE/f/nope" | tr -d '\r\n')"
check facet_m_404 404 "$(code "$B/$NODE/m/x")"
check facet_m_body "FACET_UNAVAILABLE: m" "$(curl -s "$B/$NODE/m/x" | tr -d '\r\n')"
check docs_alias_bytes_equal 0 "$(cmp -s <(curl -s "$B/docs/") <(curl -s "$B/$NODE/docs/"); echo $?)"
# An UNKNOWN label is not a peer: ADR-0056 Am.1 order ends at the docs compat surface (webserve.rs:307),
# so it answers the docs 404, never a 502. The peer-502 arm needs a seeded roster and is pinned by
# webserve_e2e.rs:259-262 (green in battery #3).
check unknown_node_docs_404 404 "$(code "$B/nosuchnode-zz/x")"

n1=$("$SPT" serve add "$(W "$SRC/one/report.md")" 2>/dev/null | grep -oE '/f/[^ ]+ \[' | head -1 | sed -E 's#^/f/##; s# \[$##')
n2=$("$SPT" serve add "$(W "$SRC/two/report.md")" 2>/dev/null | grep -oE '/f/[^ ]+ \[' | head -1 | sed -E 's#^/f/##; s# \[$##')
check first_bare_name report.md "$n1"
check second_suffixed report~1.md "$n2"
check f_first_200 200 "$(code "$B/$NODE/f/report.md")"
check f_first_body one "$(curl -s "$B/$NODE/f/report.md" | tr -d '\r\n')"
"$SPT" serve rm report.md >/dev/null 2>&1; check rm_first 0 $?
check f_first_404_after_rm 404 "$(code "$B/$NODE/f/report.md")"
n1b=$("$SPT" serve add "$(W "$SRC/one/report.md")" 2>/dev/null | grep -oE '/f/[^ ]+ \[' | head -1 | sed -E 's#^/f/##; s# \[$##')
check am2_same_path_retakes report.md "$n1b"
n3=$("$SPT" serve add "$(W "$SRC/three/report.md")" 2>/dev/null | grep -oE '/f/[^ ]+ \[' | head -1 | sed -E 's#^/f/##; s# \[$##')
check third_gets_tilde2 report~2.md "$n3"
check list_json_count 3 "$("$SPT" serve list --json 2>/dev/null | grep -o '"served_name"' | wc -l | tr -d ' ')"
check index_lists_report 1 "$(curl -s "$B/$NODE/" | grep -c 'report~2.md' | sed 's/^[1-9][0-9]*$/1/')"

"$SPT" adapter add "$(W "$SRC/mock")" >"$HOME_DIR/adapter-add.log" 2>&1; check adapter_add 0 $?
WEB="$HOME_DIR/adapters/mock/web"; [ -d "$WEB" ]; check web_dir_created 0 $?
check a_facet_empty_404 404 "$(code "$B/$NODE/a/mock/index.html")"
echo "<h1>hi</h1>" > "$WEB/index.html"
check a_facet_200 200 "$(code "$B/$NODE/a/mock/index.html")"
check alias_200 200 "$(code "$B/$NODE/reports/index.html")"
"$SPT" adapter remove mock --force >"$HOME_DIR/adapter-rm.log" 2>&1; check adapter_remove 0 $?
check a_facet_404_after_remove 404 "$(code "$B/$NODE/a/mock/index.html")"
check alias_404_after_remove 404 "$(code "$B/$NODE/reports/index.html")"
[ -f "$WEB/index.html" ]; check bytes_retained 0 $?
"$SPT" adapter add "$(W "$SRC/mock")" >"$HOME_DIR/adapter-add2.log" 2>&1; check adapter_readd 0 $?
check alias_stable_no_tilde1 200 "$(code "$B/$NODE/reports/index.html")"
check no_reports_tilde1 404 "$(code "$B/$NODE/reports~1/index.html")"
echo "unknown-key probe:"; printf '[adapter]\nname="typo"\nkind="harness"\nversion="1.0.0"\nmin_spt_core_version="0.1.0"\nhostable_types=["LiveAgent"]\nweb_short_pth="x"\n' > "$SRC/typo.toml"; mkdir -p "$SRC/typo"; mv "$SRC/typo.toml" "$SRC/typo/manifest.toml"
"$SPT" adapter add "$(W "$SRC/typo")" >"$HOME_DIR/typo.log" 2>&1; check typo_registers 0 $?
check typo_named 1 "$(grep -c 'unknown key \[adapter\].web_short_pth' "$HOME_DIR/typo.log")"

"$SPT" node stop --force >/dev/null 2>&1; check daemon_stop 0 $?
echo "FAILS=$fails home=$HOME_DIR"; exit $fails
