#!/usr/bin/env bash
# Pre-commit hook: enforce CI's blocking checks locally so a bad commit
# never reaches the remote.
#
#   1. cargo fmt --all -- --check    (fast: <1s)
#   2. cargo clippy -- -D warnings   (slow: 5-30s cold, <2s incrementally)
#
# This hook lives in .githooks/ (committed) instead of .git/hooks/ (untracked)
# so every clone gets the same enforcement. Each contributor wires it up once:
#
#   git config core.hooksPath .githooks
#
# README's "Development" section repeats this. The hook is silent on success
# and prints the offending output on failure. Bypass with `git commit --no-verify`
# when you need to (for fix-it-up commits before squash, etc.).
#
# `HVAC_SKIP_CLIPPY=1 git commit ...` skips just the slow check while keeping
# fmt enforcement — useful when you've already run clippy manually and just
# want to amend a comment.

set -eu

# No cargo / no rustfmt → no enforcement (e.g. a docs-only commit on a machine
# without the Rust toolchain). Skipping is preferable to blocking.
if ! command -v cargo >/dev/null 2>&1; then
    exit 0
fi
if ! cargo fmt --version >/dev/null 2>&1; then
    exit 0
fi

# Only run when at least one .rs file is staged. Pure-docs / config commits
# don't need to wait for the Rust toolchain to start up.
if ! git diff --cached --name-only --diff-filter=ACMR | grep -q '\.rs$'; then
    exit 0
fi

# ── 1. cargo fmt ─────────────────────────────────────────────────────────────
if ! cargo fmt --all -- --check >/dev/null 2>&1; then
    echo "✖ cargo fmt --check failed. Offending diff:" >&2
    cargo fmt --all -- --check >&2 || true
    echo "" >&2
    echo "Fix with:  cargo fmt --all" >&2
    exit 1
fi

# ── 2. cargo clippy ──────────────────────────────────────────────────────────
if [[ "${HVAC_SKIP_CLIPPY:-0}" == "1" ]]; then
    exit 0
fi
if ! cargo clippy --version >/dev/null 2>&1; then
    # clippy not installed — print on every commit (no state, no caching),
    # and let the commit through. CI will catch anything we miss; blocking
    # here would punish minimal toolchains.
    echo "⚠ cargo clippy not installed; skipping clippy check (CI still runs it)." >&2
    exit 0
fi

# Mirror CI exactly: .github/workflows/ci.yml runs `cargo clippy -- -D warnings`
# (no --all-targets — tests aren't lint-gated there). If CI ever broadens to
# --all-targets, broaden here too in lockstep.
clippy_log=$(mktemp -t hvac-clippy.XXXXXX)
trap 'rm -f "$clippy_log"' EXIT
if ! cargo clippy -- -D warnings >"$clippy_log" 2>&1; then
    echo "✖ cargo clippy -- -D warnings failed:" >&2
    cat "$clippy_log" >&2
    echo "" >&2
    echo "Either fix the lints or bypass once with:  HVAC_SKIP_CLIPPY=1 git commit ..." >&2
    exit 1
fi
