#!/bin/sh
# =============================================================================
# Pre-Commit Gate (delegates to pre-commit framework)
# =============================================================================
#
# This hook is a thin wrapper. All check logic lives in
# .pre-commit-config.yaml, which is the single source of truth.
#
# If pre-commit is not installed, a comprehensive fallback runs:
#   - TypeScript type check (blocks commits with TS errors — saves 15+ min/CI)
#   - ESLint quick check (zero warnings)
#   - Python lint via ruff
#   - Python syntax validation (py_compile) on staged .py files
#   - .env file blocking
#
# Total fallback budget: under 15 seconds
# =============================================================================

echo "Pre-Commit Gate"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

# ---------------------------------------------------------------------------
# Auto-format staged Python files BEFORE pre-commit runs.
# This prevents ruff-format from modifying files during the hook, which
# causes the commit to fail and can leave git in detached HEAD state.
# ---------------------------------------------------------------------------
STAGED_PY_FILES=$(git diff --cached --name-only --diff-filter=ACMR -- 'backend/*.py')
if [ -n "$STAGED_PY_FILES" ] && command -v ruff &> /dev/null; then
  echo "$STAGED_PY_FILES" | xargs ruff format --line-length=100 --quiet 2>/dev/null
  echo "$STAGED_PY_FILES" | xargs git add
fi

# Delegate to pre-commit framework (single source of truth)
if command -v pre-commit &> /dev/null; then
  pre-commit run --hook-stage commit || exit 1
else
  echo "Warning: pre-commit not installed. Run: pip install pre-commit && pre-commit install"
  echo "Running fallback checks..."

  # =========================================================================
  # Detect what changed
  # =========================================================================
  STAGED_PY=$(git diff --cached --name-only --diff-filter=ACMR -- '*.py')
  STAGED_TS=$(git diff --cached --name-only --diff-filter=ACMR -- '*.ts' '*.tsx')
  STAGED_FRONTEND=$(git diff --cached --name-only --diff-filter=ACMR -- 'frontend/*')
  STAGED_BACKEND=$(git diff --cached --name-only --diff-filter=ACMR -- 'backend/*')

  # =========================================================================
  # Frontend: TypeScript type check (NON-NEGOTIABLE per CLAUDE.md)
  # Catches TS errors locally instead of wasting 15+ min in CI
  # =========================================================================
  if [ -n "$STAGED_FRONTEND" ]; then
    echo ""
    echo "[1/3] TypeScript type check..."
    if command -v npx &> /dev/null && [ -f "frontend/tsconfig.json" ]; then
      if ! (cd frontend && npx tsc --noEmit --pretty 2>&1 | head -30); then
        echo ""
        echo "TypeScript errors detected. Fix before committing."
        echo "Run: cd frontend && npx tsc --noEmit"
        exit 1
      fi
      echo "TypeScript OK"
    else
      echo "Warning: npx or tsconfig.json not found, skipping TS check"
    fi

    echo "[2/3] ESLint quick check..."
    if command -v npx &> /dev/null && [ -f "frontend/.eslintrc.json" ] || [ -f "frontend/eslint.config.mjs" ]; then
      if ! (cd frontend && npx eslint . --max-warnings 0 --quiet 2>&1 | tail -5); then
        echo ""
        echo "ESLint errors detected. Fix before committing."
        exit 1
      fi
      echo "ESLint OK"
    fi
  else
    echo "[1/3] No frontend changes — skipping TS/ESLint"
  fi

  # =========================================================================
  # Backend: Ruff lint + Python syntax check
  # =========================================================================
  if [ -n "$STAGED_BACKEND" ]; then
    echo "[3/3] Python lint (ruff)..."
    if command -v ruff &> /dev/null; then
      if ! ruff check backend/app --quiet 2>&1 | tail -5; then
        echo ""
        echo "Ruff lint errors detected. Fix before committing."
        echo "Run: ruff check backend/app --fix"
        exit 1
      fi
      echo "Ruff OK"
    else
      echo "Warning: ruff not installed, falling back to py_compile"
      # Fallback: minimal Python syntax check on staged files
      if [ -n "$STAGED_PY" ]; then
        for file in $STAGED_PY; do
          if [ -f "$file" ]; then
            python3 -m py_compile "$file" 2>/dev/null || {
              echo "Syntax error in $file"
              exit 1
            }
          fi
        done
        echo "Python syntax OK"
      fi
    fi
  else
    echo "[3/3] No backend changes — skipping Python lint"
  fi

  # =========================================================================
  # Block .env files (always)
  # =========================================================================
  STAGED_ENV=$(git diff --cached --name-only --diff-filter=ACMR -- '.env*')
  if [ -n "$STAGED_ENV" ]; then
    for f in $STAGED_ENV; do
      case "$f" in
        *.env.example) ;; # Allow .env.example
        *) echo ".env file cannot be committed: $f"; exit 1 ;;
      esac
    done
  fi

  # =========================================================================
  # Validate pnpm lockfile consistency
  # =========================================================================
  if [ -n "$STAGED_FRONTEND" ]; then
    STAGED_PKG=$(git diff --cached --name-only --diff-filter=ACMR -- 'frontend/package.json')
    STAGED_LOCK=$(git diff --cached --name-only --diff-filter=ACMR -- 'frontend/pnpm-lock.yaml')
    if [ -n "$STAGED_PKG" ] && [ -z "$STAGED_LOCK" ]; then
      echo ""
      echo "Warning: frontend/package.json changed but pnpm-lock.yaml not staged."
      echo "Run: cd frontend && pnpm install && git add frontend/pnpm-lock.yaml"
    fi
  fi
fi

echo ""
echo "Pre-commit gate passed"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━"

# ─────────────────────────────────────────────────────────────────
# ARQERA governance gate (Phase 3a)
# ─────────────────────────────────────────────────────────────────
# Calls /api/v1/governance/gate/evaluate for every staged file. Blocks
# the commit on BLOCK decisions. Falls back to local stub if backend
# is unreachable. Bypass: ARQERA_GATE_DISABLE=1 git commit -m "..."
PREFLIGHT_GATE="$(git rev-parse --show-toplevel 2>/dev/null)/scripts/preflight-gate.sh"
if [ -x "$PREFLIGHT_GATE" ]; then
  "$PREFLIGHT_GATE" || exit 1
fi
