#!/usr/bin/env bash
# Pre-push hook: Run all checks before pushing to prevent CI failures
# Enterprise-grade: Mirrors CI checks exactly to catch failures locally
#
# Order: baseline integrity → pre-commit --all-files → CRLF guard → Python tests → TS checks
#
# This hook ensures NO code reaches CI that would fail. If it passes here, CI passes.
#
# Requires bash for pipefail support (available via Git Bash on Windows)

set -eo pipefail  # Exit on first error, including pipeline failures

# =============================================================================
# Baseline Integrity Check (must fail fast before any test execution)
# =============================================================================
echo "[pre-push] Running baseline integrity check..."
node .github/scripts/check-baseline-integrity.js
if [ $? -ne 0 ]; then
    echo ""
    echo "[pre-push] ❌ Push blocked: Baseline integrity check failed"
    echo "[pre-push] Run 'npm run perf:update-baseline' in extension/ to update baselines properly"
    exit 1
fi
echo "[pre-push] ✅ Baseline integrity check passed"

# =============================================================================
# Pre-commit --all-files (mirrors CI: pre-commit run --all-files)
# =============================================================================
# This catches issues that pre-commit on staged files might miss:
# - Files modified after staging
# - Files not included in the commit but changed
# - Ensures entire codebase passes linting
echo ""
echo "[pre-push] Running pre-commit on all files (mirrors CI)..."

# Detect pre-commit installation
if command -v pre-commit >/dev/null 2>&1; then
    PRE_COMMIT="pre-commit"
elif [ -f ".venv/Scripts/pre-commit.exe" ]; then
    PRE_COMMIT=".venv/Scripts/pre-commit.exe"
elif [ -f ".venv/bin/pre-commit" ]; then
    PRE_COMMIT=".venv/bin/pre-commit"
else
    echo ""
    echo "[pre-push] ❌ pre-commit not found!"
    echo "[pre-push] Install with: pip install pre-commit"
    exit 1
fi

$PRE_COMMIT run --all-files
if [ $? -ne 0 ]; then
    echo ""
    echo "[pre-push] ❌ Push blocked: pre-commit checks failed"
    echo "[pre-push] Run 'pre-commit run --all-files' to see details"
    exit 1
fi
echo "[pre-push] ✅ Pre-commit checks passed"

# =============================================================================
# CRLF Line Ending Guard (mirrors CI: line-ending-guard job)
# =============================================================================
# Prevents "works locally, fails in CI" issues on Windows
# Uses NUL-delimited file handling to prevent shell injection via crafted filenames
# The -- separator prevents option injection from filenames starting with -
echo ""
echo "[pre-push] Running CRLF line ending guard..."
FOUND_CRLF=false

# Check Husky hooks (NUL-delimited for safe filename handling)
if find .husky/ -type f -print0 2>/dev/null | xargs -0 grep -l -- $'\r' 2>/dev/null; then
    echo "[pre-push] ❌ CRLF detected in .husky/"
    FOUND_CRLF=true
fi

# Check shell scripts (NUL-delimited)
if find . -name "*.sh" -type f -not -path "./node_modules/*" -not -path "./.venv/*" -print0 2>/dev/null | xargs -0 grep -l -- $'\r' 2>/dev/null; then
    echo "[pre-push] ❌ CRLF detected in *.sh files"
    FOUND_CRLF=true
fi

# Check .github/scripts (NUL-delimited)
if find .github/scripts/ -type f -print0 2>/dev/null | xargs -0 grep -l -- $'\r' 2>/dev/null; then
    echo "[pre-push] ❌ CRLF detected in .github/scripts/"
    FOUND_CRLF=true
fi

# Check scripts directory (NUL-delimited)
if find scripts/ -type f -print0 2>/dev/null | xargs -0 grep -l -- $'\r' 2>/dev/null; then
    echo "[pre-push] ❌ CRLF detected in scripts/"
    FOUND_CRLF=true
fi

# Check extension scripts (NUL-delimited)
if find extension/scripts/ -type f -print0 2>/dev/null | xargs -0 grep -l -- $'\r' 2>/dev/null; then
    echo "[pre-push] ❌ CRLF detected in extension/scripts/"
    FOUND_CRLF=true
fi

# Check extension UI files (NUL-delimited, catches CRLF from npm packages)
if find extension/ui/ -type f -print0 2>/dev/null | xargs -0 grep -l -- $'\r' 2>/dev/null; then
    echo "[pre-push] ❌ CRLF detected in extension/ui/"
    echo "[pre-push] If copying from npm, use: cd extension && node scripts/copy-vss-sdk.mjs"
    FOUND_CRLF=true
fi

if [ "$FOUND_CRLF" = true ]; then
    echo ""
    echo "[pre-push] ❌ Push blocked: CRLF line endings found"
    echo "[pre-push] Fix: Run 'git add --renormalize .' after checking .gitattributes"
    exit 1
fi
echo "[pre-push] ✅ CRLF guard passed"

# =============================================================================
# Python Type Check (mypy) - Immutable Invariant per FR-016
# =============================================================================
echo ""
echo "[pre-push] Running mypy type check..."
echo "[pre-push] Command: python -m mypy src/"

# Detect mypy installation
if command -v mypy >/dev/null 2>&1; then
    MYPY="mypy"
elif python -m mypy --version >/dev/null 2>&1; then
    MYPY="python -m mypy"
else
    echo ""
    echo "[pre-push] ❌ mypy not found!"
    echo "[pre-push] Install with: pip install mypy"
    exit 1
fi

$MYPY src/
if [ $? -ne 0 ]; then
    echo ""
    echo "[pre-push] ❌ Push blocked: mypy type check failed"
    echo "[pre-push] Run 'mypy src/' to see full output"
    echo "[pre-push] Fix type errors or add justified type: ignore comments"
    exit 1
fi
echo "[pre-push] ✅ mypy type check passed"

# =============================================================================
# Python Tests (with coverage threshold enforcement)
# =============================================================================
echo ""
echo "[pre-push] Running Python tests with coverage..."
# Coverage threshold (fail_under = 70) is enforced via pyproject.toml
# This ensures local/CI parity for coverage requirements
python -m pytest tests/ -q
if [ $? -ne 0 ]; then
    echo ""
    echo "[pre-push] ❌ Push blocked: Python tests or coverage threshold failed"
    exit 1
fi
echo "[pre-push] ✅ Python tests passed"

# =============================================================================
# TypeScript Type Check (fresh, no cache - catches declaration conflicts)
# =============================================================================
echo ""
echo "[pre-push] Running TypeScript type check (fresh)..."
cd extension

# Clear tsc incremental cache for fresh check (catches declaration merging issues)
rm -f tsconfig.tsbuildinfo 2>/dev/null

npx tsc --noEmit
if [ $? -ne 0 ]; then
    echo ""
    echo "[pre-push] ❌ Push blocked: TypeScript type check failed"
    exit 1
fi
echo "[pre-push] ✅ TypeScript type check passed"

# =============================================================================
# ESLint Check (mirrors CI extension-tests job)
# =============================================================================
echo ""
echo "[pre-push] Running ESLint..."
npm run lint
if [ $? -ne 0 ]; then
    echo ""
    echo "[pre-push] ❌ Push blocked: ESLint check failed"
    exit 1
fi
echo "[pre-push] ✅ ESLint check passed"

# =============================================================================
# TypeScript Tests (with coverage threshold enforcement)
# =============================================================================
echo ""
echo "[pre-push] Running extension tests with coverage..."
# Coverage threshold is enforced via jest.config.ts coverageThreshold
# Uses test:ci base + --coverage for threshold enforcement with CI reporters
npm run test:ci -- --coverage
if [ $? -ne 0 ]; then
    echo ""
    echo "[pre-push] ❌ Push blocked: Extension tests or coverage threshold failed"
    exit 1
fi

echo "[pre-push] ✅ All pre-push checks passed"
