#!/bin/bash
set -euo pipefail

REPO_ROOT="$(git rev-parse --show-toplevel)"

# ── Data-loss guard (runs first, < 50ms, NOT skippable) ──────────
# Catches files corrupted by lean-ctx shadow-mode compression markers.
# These appear when an edit tool reads through ctx_read and writes the
# compressed output back as file content. See: #1301, #1302
marker_hits=""
while IFS= read -r file; do
    # Skip Rust source, test files, and hook infrastructure — they contain
    # marker literals in assertions/detection logic, and Rust corruption is
    # caught by the cargo clippy check later in this hook.
    case "$file" in
        *.rs|*.githooks/*|*tests/*) continue ;;
    esac
    if git show ":$file" 2>/dev/null | grep -qF -- '[lean-ctx: omitted'; then
        marker_hits="$marker_hits  - $file"$'\n'
    fi
done < <(git diff --cached --name-only --diff-filter=d)

if [ -n "$marker_hits" ]; then
    echo ""
    echo "╔══════════════════════════════════════════════════════════════╗"
    echo "║  BLOCKED: lean-ctx compression markers in staged files     ║"
    echo "╠══════════════════════════════════════════════════════════════╣"
    echo "║                                                            ║"
    echo "║  These files contain '[lean-ctx: omitted N lines]' text    ║"
    echo "║  that was written by a corrupted edit tool read.           ║"
    echo "║                                                            ║"
    echo "║  Fix: restore from the last clean commit:                  ║"
    echo "║    LEAN_CTX_DISABLE=1 git restore --source=HEAD -- <file>  ║"
    echo "║                                                            ║"
    echo "╚══════════════════════════════════════════════════════════════╝"
    echo ""
    echo "Affected files:"
    echo "$marker_hits"
    exit 1
fi

# Also catch the ctx_compose footer marker and build_header corruption (#1323)
while IFS= read -r file; do
    case "$file" in
        *.rs|*.githooks/*|*tests/*) continue ;;
    esac
    staged=$(git show ":$file" 2>/dev/null) || continue
    if echo "$staged" | grep -qF -- '--- lean-ctx:'; then
        echo "pre-commit: BLOCKED — '$file' contains lean-ctx footer marker."
        echo "  Fix: LEAN_CTX_DISABLE=1 git restore --source=HEAD -- $file"
        exit 1
    fi
    # Detect ctx_read build_header corruption: "filename.ext NNL" on first line
    if echo "$staged" | head -2 | grep -qE '^[^ ]+\.[a-z]+ [0-9]+L$'; then
        if echo "$staged" | sed -n '2p' | grep -qE '^ (deps|exports) '; then
            echo "pre-commit: BLOCKED — '$file' contains ctx_read header corruption."
            echo "  Fix: LEAN_CTX_DISABLE=1 git restore --source=HEAD -- $file"
            exit 1
        fi
    fi
    # Detect cognitive/signatures mode section markers (#1444)
    if echo "$staged" | grep -qF '§ function'; then
        echo "pre-commit: BLOCKED — '$file' contains §-section markers (cognitive mode corruption)."
        echo "  Fix: LEAN_CTX_DISABLE=1 git restore --source=HEAD -- $file"
        exit 1
    fi
    if echo "$staged" | grep -qF '§ block'; then
        echo "pre-commit: BLOCKED — '$file' contains §-section markers (cognitive mode corruption)."
        echo "  Fix: LEAN_CTX_DISABLE=1 git restore --source=HEAD -- $file"
        exit 1
    fi
    if echo "$staged" | grep -qF '§ impl'; then
        echo "pre-commit: BLOCKED — '$file' contains §-section markers (cognitive mode corruption)."
        echo "  Fix: LEAN_CTX_DISABLE=1 git restore --source=HEAD -- $file"
        exit 1
    fi
done < <(git diff --cached --name-only --diff-filter=d)

# ── Rust quality checks ──────────────────────────────────────────
cd "$REPO_ROOT/rust"

if ! cargo fmt --check 2>/dev/null; then
    echo "pre-commit: formatting check failed. Run 'cargo fmt' first."
    exit 1
fi

# Production code: strict — unwrap_used is DENIED
if ! cargo clippy --lib --bins --examples -- -D warnings -A clippy::too_many_lines 2>/dev/null; then
    echo "pre-commit: clippy check failed (production). Fix warnings before committing."
    exit 1
fi

# Test code: unwrap() is idiomatic in tests — allow it
if ! cargo clippy --tests -- -D warnings -A clippy::too_many_lines -A clippy::unwrap_used 2>/dev/null; then
    echo "pre-commit: clippy check failed (tests). Fix warnings before committing."
    exit 1
fi

# Generated reference docs must match the tool/config definitions —
# the CI Documentation job runs the same check and fails otherwise.
if git diff --cached --name-only | grep -qE '^rust/src/(tools|tool_defs|core/config)'; then
    if ! cargo run --quiet --example gen_docs --features dev-tools -- --check 2>/dev/null; then
        echo "pre-commit: generated docs out of date. Run: cd rust && cargo run --example gen_docs --features dev-tools"
        exit 1
    fi
fi

# The committed testbench recording must match the fixtures + assembly/judge framing —
# the CI Documentation job runs the same check (#611).
if git diff --cached --name-only | grep -qE '^rust/(eval/testbench/|src/core/eval_ab/)'; then
    if ! cargo run --quiet --example gen_testbench_recording --features dev-tools -- --check 2>/dev/null; then
        echo "pre-commit: testbench recording out of date. Run: cd rust && cargo run --example gen_testbench_recording --features dev-tools"
        exit 1
    fi
fi
