#!/bin/sh
set -eu

root=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
cd "$root"

fail() {
  printf 'release verification failed: %s\n' "$1" >&2
  exit 1
}

require_file() {
  [ -f "$1" ] || fail "missing $1"
}

approved_release_files() {
  cat <<'EOF'
.gitignore
LICENSE
README.md
SHA256SUMS
evidence/pins.json
evidence/run-evidence.json
index.html
pages/claim-1.md
pages/claim-2.md
pages/judge-evidence.md
scripts/test_verify_release_negative.sh
scripts/test_verify_release_unexpected_file.sh
scripts/verify_release.sh
EOF
}

verify_release_inventory() {
  expected_files=$(approved_release_files | LC_ALL=C sort)
  actual_files=$(find . -path './.git' -prune -o \( -type f -o -type l \) -print | sed 's|^./||' | LC_ALL=C sort)

  [ "$actual_files" = "$expected_files" ] || fail 'release file inventory does not match the approved allowlist'

  expected_hashed_files=$(approved_release_files | grep -Fvx 'SHA256SUMS' | LC_ALL=C sort)
  manifest_files=$(awk '{ print $2 }' SHA256SUMS | LC_ALL=C sort)

  [ "$manifest_files" = "$expected_hashed_files" ] || fail 'SHA256SUMS does not cover exactly the approved release files'
}

verify_judge_pins() {
  pins_file=$1

  [ -f "$pins_file" ] || fail "missing $pins_file"
  command -v jq >/dev/null 2>&1 || fail 'jq is required for structural judge-pin verification'

  if ! jq -e \
    --arg revision '7b5b56aebf3abe590eab9f2c241a796125cab928' \
    --arg legacy_etag 'f8b74517cd33712f80399eea913efac0bb41078f' \
    --arg legacy_hash 'af5ab2d62f786ae36861957cbd08b4188f6d4c86e67152becc661a9c5bbb9d57' \
    --arg anchored_etag '4093a21c968f9e7e6a33f495fe0e59bb37fe912d' \
    --arg anchored_hash 'eb3f2d878646ca5c40da121741a613c1f9e1e10c14845f373db107e74a4ef439' \
    '
      .judge_inputs as $inputs |
      ($inputs.challenge_revision == $revision) and
      ($inputs.legacy.file == "claims.json") and
      ($inputs.legacy.revision == $revision) and
      ($inputs.legacy.etag == $legacy_etag) and
      ($inputs.legacy.full_file_sha256 == $legacy_hash) and
      ($inputs.anchored.file == "claims_anchored.json") and
      ($inputs.anchored.revision == $revision) and
      ($inputs.anchored.etag == $anchored_etag) and
      ($inputs.anchored.full_file_sha256 == $anchored_hash) and
      ($inputs.active_merge.policy == "anchored_overrides_legacy") and
      ($inputs.active_merge.target_paper_id == "w0JhOFWPJl") and
      ($inputs.active_merge.active_source == "claims_anchored.json")
    ' "$pins_file" >/dev/null; then
    fail 'judge input tuples or active merge policy mismatch'
  fi
}

if [ "${1:-}" = '--check-pins' ]; then
  [ "$#" = 2 ] || fail 'usage: verify_release.sh --check-pins PATH'
  verify_judge_pins "$2"
  printf 'judge pin verification: OK\n'
  exit 0
fi

[ "$#" = 0 ] || fail 'usage: verify_release.sh [--check-pins PATH]'

for file in $(approved_release_files); do
  require_file "$file"
done

verify_release_inventory

grep -Fx 'sdk: static' README.md >/dev/null || fail 'README sdk is not static'
grep -Fx 'app_file: index.html' README.md >/dev/null || fail 'README app_file is not index.html'
grep -Fx '  - icml2026-repro' README.md >/dev/null || fail 'missing icml2026-repro discovery tag'
grep -Fx '  - paper-w0JhOFWPJl' README.md >/dev/null || fail 'missing paper-w0JhOFWPJl discovery tag'
grep -Fx 'license: mit' README.md >/dev/null || fail 'README does not declare MIT licence'

page_count=$(find pages -type f -name '*.md' -print | wc -l | tr -d ' ')
[ "$page_count" -ge 3 ] || fail 'judge evidence pages are incomplete'
page_characters=$(find pages -type f -name '*.md' -exec cat {} + | sed -E 's/`[^`]*`//g; s/\[[^]]*\]\([^)]*\)//g; s/[#>*_`|()-]//g' | tr -d '[:space:]' | wc -c | tr -d ' ')
[ "$page_characters" -ge 200 ] || fail 'combined stripped Markdown pages are shorter than 200 characters'
grep -F 'anchored overrides legacy' pages/judge-evidence.md >/dev/null || fail 'judge merge precedence is not documented under pages'

shasum -a 256 --check SHA256SUMS

grep -F '"source_commit": "cc1664bf48505d7bac308b308ce1c495b06ce979"' evidence/run-evidence.json >/dev/null || fail 'source commit pin mismatch'
grep -F '"source_tree_sha256": "bfa533902a89fd43e1e1992f134320bbe847508a129506dcde69f2c20dd62098"' evidence/run-evidence.json >/dev/null || fail 'source tree pin mismatch'
grep -F '"source_script_sha256": "44ea2d201fddc2db01a860c40dcc87900997b76a1ce7b5fa5acf0d89aa0af74d"' evidence/run-evidence.json >/dev/null || fail 'source script pin mismatch'
grep -F '"environment_freeze_sha256": "1963bca7c0a462c1fca202d5cf7d290ef824e376bb79be1b0992f1ffa250b14e"' evidence/run-evidence.json >/dev/null || fail 'environment pin mismatch'
grep -F '"relu": 40.29' evidence/run-evidence.json >/dev/null || fail 'ReLU boundary mismatch'
grep -F '"reglu": 3.68' evidence/run-evidence.json >/dev/null || fail 'ReGLU boundary mismatch'
grep -F '**Unverified.**' pages/claim-2.md >/dev/null || fail 'claim 2 is not explicitly unverified'
verify_judge_pins evidence/pins.json

if find . -type f \( -name '*.py' -o -name '*.js' -o -name '*.ipynb' -o -name '*.log' \) -print | grep -q .; then
  fail 'active or raw-log content is present'
fi
if find . -type d \( -name source -o -name venv -o -name .venv -o -name run \) -print | grep -q .; then
  fail 'author source, environment, or run directory is present'
fi
if find . -type f -path './evidence/*' -name '*claim*' -print | grep -q .; then
  fail 'judge evidence must live only under pages/*.md'
fi
if grep -R -n -E '/Users/|HF_TOKEN|api[_-]?key|BEGIN [A-Z ]*PRIVATE KEY' \
  --exclude=verify_release.sh --exclude=SHA256SUMS . >/dev/null 2>&1; then
  fail 'private path or credential-like content is present'
fi

printf 'release verification: OK\n'
