#!/usr/bin/env bash
# Pre-commit hook: mirrors GitHub CI checks locally.
# Installed via: git config core.hooksPath .githooks
#
# Runs on every `git commit`. Catches format/lint/test failures before push.

set -euo pipefail

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

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

_ok() { echo -e "${GREEN}✓${NC} $1"; }
_fail() { echo -e "${RED}✗${NC} $1"; }
_info() { echo -e "${YELLOW}→${NC} $1"; }

echo ""
_info "Running pre-commit checks (mirrors GitHub CI)..."
echo ""

# Only check staged shell/Go files to keep commits fast.
STAGED=$(git diff --cached --name-only --diff-filter=ACM)
HAS_SHELL=$(echo "$STAGED" | grep -E '\.sh$|^mole$|^bin/' || true)
HAS_GO=$(echo "$STAGED" | grep -E '\.go$' || true)

FAILED=0

# --- 1. Shell syntax check (fast, no tool required) ---
if [[ -n "$HAS_SHELL" ]]; then
    _info "Shell syntax check..."
    while IFS= read -r f; do
        [[ -f "$f" ]] || continue
        if ! bash -n "$f" 2>&1; then
            _fail "Syntax error: $f"
            FAILED=1
        fi
    done <<< "$HAS_SHELL"
    [[ $FAILED -eq 0 ]] && _ok "Shell syntax clean"
fi

# --- 2. shfmt format check (if installed) ---
if [[ -n "$HAS_SHELL" ]] && command -v shfmt > /dev/null 2>&1; then
    _info "shfmt format check..."
    UNFORMATTED=""
    while IFS= read -r f; do
        [[ -f "$f" ]] || continue
        if ! shfmt -i 4 -ci -sr -d "$f" > /dev/null 2>&1; then
            UNFORMATTED="$UNFORMATTED $f"
        fi
    done <<< "$HAS_SHELL"
    if [[ -n "$UNFORMATTED" ]]; then
        _fail "shfmt: unformatted files:$UNFORMATTED"
        _info "Fix with: ./scripts/check.sh --format"
        FAILED=1
    else
        _ok "shfmt format clean"
    fi
fi

# --- 3. shellcheck (if installed) ---
if [[ -n "$HAS_SHELL" ]] && command -v shellcheck > /dev/null 2>&1; then
    _info "shellcheck..."
    while IFS= read -r f; do
        [[ -f "$f" ]] || continue
        if ! shellcheck "$f" 2>&1; then
            FAILED=1
        fi
    done <<< "$HAS_SHELL"
    [[ $FAILED -eq 0 ]] && _ok "shellcheck clean"
fi

# --- 4. Go vet (if staged Go files) ---
if [[ -n "$HAS_GO" ]] && command -v go > /dev/null 2>&1; then
    _info "go vet..."
    if go vet ./cmd/... 2>&1; then
        _ok "go vet clean"
    else
        _fail "go vet failed"
        FAILED=1
    fi
fi

echo ""
if [[ $FAILED -ne 0 ]]; then
    _fail "Pre-commit checks failed. Fix the issues above before committing."
    _info "Run './scripts/check.sh --format' to auto-fix formatting."
    echo ""
    exit 1
fi

_ok "All pre-commit checks passed."
echo ""
