#!/usr/bin/env bash
# pre-push hook — runs the EXACT same lint + test commands as GitHub Actions CI.
# Catches failures BEFORE CI, not after.
#
# To bypass in an emergency: git push --no-verify
# To install: cp scripts/hooks/pre-push .git/hooks/pre-push && chmod +x .git/hooks/pre-push
#
# CI equivalence:
#   Lint:  .github/workflows/ci.yml → lint job → ruff check src/ --select E,F,W --ignore E501
#   Tests: .github/workflows/ci.yml → unit-tests job → pytest (matches pyproject testpaths)
#
# Layer 0 discipline (per docs/working/ci-hygiene-plan-2026-04-28.md):
#   - Warns when origin/main's last CI run was a failure.
#   - Refuses to push onto red main without --no-verify.

set -euo pipefail

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

# Activate venv if not already active
if [ -z "${VIRTUAL_ENV:-}" ]; then
  if [ -f "$REPO_ROOT/../.venv/bin/activate" ]; then
    # shellcheck disable=SC1091
    source "$REPO_ROOT/../.venv/bin/activate"
  elif [ -f "$REPO_ROOT/.venv/bin/activate" ]; then
    source "$REPO_ROOT/.venv/bin/activate"
  fi
fi

# ── CI status check on origin/main — Layer 0 discipline ────────────────
# Warn if last CI run on main was a failure. Cheap; uses gh CLI auth that's
# already configured. Skip gracefully if gh isn't available or repo isn't on
# GitHub.
if command -v gh >/dev/null 2>&1; then
  echo "▶ pre-push: checking origin/main CI status..."
  last_status=$(gh run list --branch main --limit 1 --json conclusion --jq '.[0].conclusion' 2>/dev/null || echo "unknown")
  if [ "$last_status" = "failure" ]; then
    echo ""
    echo "⚠ pre-push: origin/main is RED (last CI run failed)."
    echo "   View: gh run list --branch main --limit 5"
    echo ""
    echo "   Per ci-hygiene-plan-2026-04-28.md Rule 1: never push onto red main."
    echo "   Fix or revert is the next commit, not a new feature."
    echo ""
    echo "   To bypass intentionally: git push --no-verify"
    echo ""
    exit 1
  elif [ "$last_status" = "success" ]; then
    echo "✓ pre-push: origin/main is GREEN"
  else
    echo "  (origin/main status: ${last_status} — proceeding)"
  fi
fi

# ── Ruff lint (EXACT match with CI lint job) ────────────────────────────
echo "▶ pre-push: running ruff linter..."

if ruff check src/ --select E,F,W --ignore E501; then
  echo "✓ pre-push: ruff passed"
else
  echo ""
  echo "✗ pre-push: ruff found errors — push blocked"
  echo "  Run: ruff check src/ --select E,F,W --ignore E501 --fix"
  exit 1
fi

# ── Test suite (matches CI unit-tests job — both testpaths) ────────────
# CI uses pyproject.toml's testpaths: ["tests", "src/axiom/extensions/builtins"].
# Earlier this hook only ran tests/ which missed ~2000 extension tests; that
# gap let test_standard collection errors + classroom test failures slip
# past pre-push for ~9 days. Now we run both, matching CI exactly.
echo "▶ pre-push: running test suite (unit only, no integration)..."

if python -m pytest tests/ src/axiom/extensions/builtins/ \
    -m "not integration" \
    --tb=short -q \
    --no-header \
    --timeout=30 \
    2>&1; then
  echo "✓ pre-push: all tests passed"
else
  echo ""
  echo "✗ pre-push: tests failed — push blocked"
  echo "  Fix the failures above, or use --no-verify to bypass"
  exit 1
fi
