#!/usr/bin/env bash
# Vector 26: status-claims-sync — whitelisted status docs must embed the
# canonical block from scripts/refresh-status.sh, structurally verbatim.
#
# Why: prevents drift between hand-written prose claims (HEAD SHA, crate
# counts, per-layer distribution) and the single source of truth. Without
# this vector, every commit that advances HEAD silently invalidates every
# doc that mentions HEAD.
#
# Comparison strategy:
# - Pre-commit speed budget (<5s) forbids running `cargo test --workspace`
#   on every check. We therefore compare STRUCTURAL fields only (branch,
#   HEAD, workspace version, crate/layer counts). The dynamic fields
#   (`lib tests`, `clippy`) are stripped before diff.
# - Full lib-tests/clippy parity stays verifiable manually via
#   `bash scripts/refresh-status.sh` (no --quick) when needed.
#
# Whitelist of docs that MUST embed the canonical block lives in
# `STATUS_DOCS` below. Add new docs by appending.
#
# Exit codes:
#   0 -- GREEN (all whitelisted docs match)
#   1 -- YELLOW (a whitelisted doc is missing — file moved/deleted)
#   2 -- RED  (block missing from a doc, or block content drifted)

set -uo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
cd "$REPO_ROOT" || exit 2

# Whitelisted status docs. Paths are relative to repo root.
# Add a new doc here AND embed the canonical block (with the marker comments)
# at the location where vector 23 should anchor.
STATUS_DOCS=(
  "ROADMAP.md"
  ".claude/CLAUDE.md"
)

# Marker emitted by scripts/refresh-status.sh as the first line of its block.
START_MARKER="<!-- AUTO-GENERATED by scripts/refresh-status.sh — do not edit by hand -->"
# Last line of the block — the clippy row of the table. Use a literal substring
# (not awk regex with `\|`, which is implementation-defined and behaves as
# alternation in some awks, matching every line).
END_PREFIX="| clippy "

# Generate canonical block in --quick mode (no cargo test/clippy — too slow
# for pre-commit). Structural fields are stable across the test/clippy skip.
CANONICAL=$(bash scripts/refresh-status.sh --quick 2>/dev/null)
if [ -z "$CANONICAL" ]; then
  echo "RED: scripts/refresh-status.sh --quick produced no output"
  exit 2
fi

# Strip dynamic fields for comparison. Three categories of "dynamic":
#   - lib tests, clippy : depend on cargo run, slow (skipped in --quick mode)
#   - HEAD              : changes every commit. Each engine commit would
#                         otherwise invalidate the embedded block, requiring
#                         a sync commit, which itself advances HEAD into a new
#                         drift. HEAD parity for tracked docs is intentionally
#                         left unenforced; vector 1 (memory-head-sha) handles
#                         the out-of-tree MEMORY.md pointer separately.
#   - branch            : tree-local, same class as HEAD. A PR branch that
#                         splices the block then squash-merges poisons main's
#                         embedded block with the feature-branch name, hard-
#                         blocking every later push from main (fired twice,
#                         2026-06-10/11 · feat/nika-pack). Committed docs on
#                         main should cosmetically say `main`, but parity on
#                         this row is structurally meaningless.
# What remains: workspace version, crate counts, per-layer
# distribution. These are the SLOWLY-changing fields where drift is
# pathological (a wrong layer count = misleading architecture claim).
strip_dynamic() {
  grep -vE '^\| (lib tests|clippy|HEAD|branch) '
}

CANONICAL_STATIC=$(echo "$CANONICAL" | strip_dynamic)

# Extract the embedded block from a doc — from START_MARKER through the line
# starting with END_PREFIX (inclusive). Uses awk's `index()` instead of regex
# to avoid ambiguity around escaping `|` in EREs.
extract_block() {
  local doc="$1"
  awk -v start="$START_MARKER" -v end="$END_PREFIX" '
    BEGIN { in_block=0 }
    $0 == start { in_block=1 }
    in_block { print }
    in_block && index($0, end) == 1 { exit }
  ' "$doc"
}

violations=0
warnings=0
log=""

for doc in "${STATUS_DOCS[@]}"; do
  if [ ! -f "$doc" ]; then
    warnings=$((warnings + 1))
    log+="\n  WARN: whitelisted doc missing: $doc (was it renamed?)"
    continue
  fi

  if ! grep -qF "$START_MARKER" "$doc"; then
    violations=$((violations + 1))
    log+="\n  RED: $doc has no canonical block (START_MARKER not found)"
    log+="\n       Insert: bash scripts/refresh-status.sh"
    continue
  fi

  embedded=$(extract_block "$doc")
  embedded_static=$(echo "$embedded" | strip_dynamic)

  if [ "$embedded_static" != "$CANONICAL_STATIC" ]; then
    violations=$((violations + 1))
    log+="\n  RED: $doc canonical block drifted from scripts/refresh-status.sh"
    log+="\n       diff (canonical → embedded):"
    diff_out=$(diff <(echo "$CANONICAL_STATIC") <(echo "$embedded_static") | head -10 | sed 's/^/         /')
    log+="\n$diff_out"
  fi
done

if [ "$violations" -gt 0 ]; then
  printf "RED: %d status-doc parity violation(s):" "$violations"
  printf "%b\n" "$log"
  echo ""
  echo "Hint: regenerate the block (\`bash scripts/refresh-status.sh\`) and"
  echo "replace each whitelisted doc's block verbatim from START_MARKER"
  echo "through the \`| clippy ...\` row. Re-run this vector to confirm."
  exit 2
fi

if [ "$warnings" -gt 0 ]; then
  printf "YELLOW: %d warning(s):" "$warnings"
  printf "%b\n" "$log"
  exit 1
fi

echo "OK: ${#STATUS_DOCS[@]} status doc(s) match canonical block (structural fields)"
exit 0
