#!/usr/bin/env bash
set -euo pipefail

echo "Pre-commit: running fast checks..."

# Commit-time checks stay owner-local. Reverse-dependency tests belong to the
# pre-push planner and CI, so an edit in one crate does not compile the world
# twice before it can be shared.
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMRD)
HAS_RUST=$(echo "$STAGED_FILES" | grep -q '\.rs$' && echo "yes" || echo "no")
HAS_RUST_INPUT=$(echo "$STAGED_FILES" | grep -Eq '(\.rs$|(^|/)Cargo\.toml$|^Cargo\.lock$|^rust-toolchain\.toml$|^clippy\.toml$)' && echo "yes" || echo "no")
HAS_APP_RUST=$(echo "$STAGED_FILES" | grep -Eq '^app/.*\.rs$' && echo "yes" || echo "no")
HAS_SHARED_RUST_CONFIG=$(echo "$STAGED_FILES" | grep -Eq '(^|/)Cargo\.toml$|^Cargo\.lock$|^rust-toolchain\.toml$|^clippy\.toml$' && echo "yes" || echo "no")

if [ "$HAS_RUST" = "yes" ]; then
    echo "  Checking Rust formatting..."
    cargo fmt --all -- --check 2>&1 || {
        echo "FAIL: Rust formatting differs. Run cargo fmt --all, review the changes, and stage them explicitly."
        exit 1
    }

fi

if echo "$STAGED_FILES" | grep -Eq '^crates/(wenlan-core|wenlan-server)/|^scripts/m5-reader-sweep\.py$'; then
    if command -v python3 >/dev/null 2>&1; then
        PYTHON_BIN=python3
    elif command -v python >/dev/null 2>&1; then
        PYTHON_BIN=python
    else
        echo "FAIL: Python is required for the M5 reader inventory check." >&2
        exit 1
    fi

    echo "  Refreshing M5 reader inventory..."
    INVENTORY=crates/wenlan-core/contracts/m5-reader-manifest-inventory.md
    "$PYTHON_BIN" scripts/m5-reader-sweep.py --update-inventory >/dev/null || {
        echo "FAIL: scripts/m5-reader-sweep.py --update-inventory failed; fix the sweep error above before committing."
        exit 1
    }

    if ! git diff --quiet -- "$INVENTORY" || ! git diff --cached --quiet -- "$INVENTORY"; then
        git add "$INVENTORY"
        echo "  M5 reader inventory refreshed and staged; review it in the diff."
    else
        echo "  M5 reader inventory up to date."
    fi

    if [ -n "$(git diff --name-only -- crates/wenlan-core crates/wenlan-server)" ]; then
        echo "  warning: unstaged Rust changes present; the inventory was generated from the working tree."
    fi
fi

if [ "$HAS_RUST_INPUT" = "yes" ]; then
    # Detect direct owners only; the pre-push hook expands the reverse closure.
    TOUCHED_CRATES=""
    if echo "$STAGED_FILES" | grep -q '^crates/wenlan-types/'; then TOUCHED_CRATES="$TOUCHED_CRATES -p wenlan-types"; fi
    if echo "$STAGED_FILES" | grep -q '^crates/wenlan-core/'; then TOUCHED_CRATES="$TOUCHED_CRATES -p wenlan-core"; fi
    if echo "$STAGED_FILES" | grep -q '^crates/wenlan-server/'; then TOUCHED_CRATES="$TOUCHED_CRATES -p wenlan-server"; fi
    if echo "$STAGED_FILES" | grep -q '^crates/wenlan-cli/'; then TOUCHED_CRATES="$TOUCHED_CRATES -p wenlan"; fi
    if echo "$STAGED_FILES" | grep -q '^crates/wenlan-mcp/'; then TOUCHED_CRATES="$TOUCHED_CRATES -p wenlan-mcp"; fi

    if [ -n "$TOUCHED_CRATES" ]; then
        echo "  Running Clippy on changed crates..."
        cargo clippy $TOUCHED_CRATES -- -D warnings 2>&1 || {
            echo "FAIL: Clippy warnings found. Fix before committing."
            exit 1
        }
    else
        # Shared graph/toolchain/Clippy inputs have no honest single-crate
        # owner. Keep commit-time feedback cheap; the fail-closed pre-push
        # planner expands these inputs to the complete workspace checks.
        if echo "$STAGED_FILES" | grep -Eq '((^|/)Cargo\.toml$|^Cargo\.lock$)'; then
            echo "  Validating Cargo metadata; full graph checks run pre-push..."
            cargo metadata --format-version 1 --locked --no-deps >/dev/null 2>&1 || {
                echo "FAIL: Cargo metadata is invalid. Fix before committing."
                exit 1
            }
        elif [ "$HAS_APP_RUST" = "yes" ] && [ "$HAS_SHARED_RUST_CONFIG" = "yes" ]; then
            echo "  CI app-check lane owns app/ Rust checks; shared Rust configuration gets full graph checks pre-push."
        elif [ "$HAS_APP_RUST" = "yes" ]; then
            echo "  CI app-check lane owns app/ Rust checks; heavy app compiles stay out of local hooks."
        elif [ "$HAS_SHARED_RUST_CONFIG" = "yes" ]; then
            echo "  Shared Rust configuration changed; full graph checks run pre-push."
        else
            echo "  No direct local crate owner; remaining Rust checks stay in CI/pre-push routing."
        fi
    fi
fi

echo "Pre-commit: all checks passed."
