#!/bin/bash
# Pre-commit hook: auto-fix formatting and fast checks
# Skip with: git commit --no-verify
#
# This hook is contextual - it only runs checks for file types that are staged.

set -e

# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
BOLD='\033[1m'
NC='\033[0m' # No Color

# Detect which file types are staged
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR)
HAS_GO_FILES=$(echo "$STAGED_FILES" | grep -E '\.go$' || true)
HAS_MD_FILES=$(echo "$STAGED_FILES" | grep -E '\.md$' || true)
HAS_TS_FILES=$(echo "$STAGED_FILES" | grep -E '\.(ts|tsx)$' || true)

# Exit early if no relevant files are staged
if [ -z "$HAS_GO_FILES" ] && [ -z "$HAS_MD_FILES" ] && [ -z "$HAS_TS_FILES" ]; then
    echo -e "${GREEN}✓${NC} No Go, Markdown, or TypeScript files staged, skipping checks"
    exit 0
fi

# Header
echo ""
echo -e "${BLUE}╔═══════════════════════════════════════════════════╗${NC}"
echo -e "${BLUE}║${NC}  ${BOLD}PRE-COMMIT CHECKS${NC}                                ${BLUE}║${NC}"
echo -e "${BLUE}╚═══════════════════════════════════════════════════╝${NC}"
echo ""

# Show what's being checked
if [ -n "$HAS_GO_FILES" ]; then
    echo -e "${YELLOW}Go files staged:${NC} $(echo "$HAS_GO_FILES" | wc -l | tr -d ' ') file(s)"
fi
if [ -n "$HAS_MD_FILES" ]; then
    echo -e "${YELLOW}Markdown files staged:${NC} $(echo "$HAS_MD_FILES" | wc -l | tr -d ' ') file(s)"
fi
if [ -n "$HAS_TS_FILES" ]; then
    echo -e "${YELLOW}TypeScript files staged:${NC} $(echo "$HAS_TS_FILES" | wc -l | tr -d ' ') file(s)"
fi
echo ""

# Track if any check fails
FAILED=0

# Go checks (only if .go files are staged)
if [ -n "$HAS_GO_FILES" ]; then
    # 1. Auto-format Go code
    echo -e "${YELLOW}▶${NC} Auto-formatting Go code..."
    if make fmt > /tmp/hook-output.txt 2>&1; then
        # Check if any files were modified
        if git diff --name-only | grep -q "\.go$"; then
            echo -e "${GREEN}✓${NC} Go code formatted (changes staged)"
            git add -u  # Stage modified tracked files
        else
            echo -e "${GREEN}✓${NC} Go code already formatted"
        fi
    else
        echo -e "${RED}✗${NC} Go formatting failed"
        cat /tmp/hook-output.txt
        FAILED=1
    fi

    # 2. Run go vet
    echo -e "${YELLOW}▶${NC} Running go vet (static analysis)..."
    if make vet > /tmp/hook-output.txt 2>&1; then
        echo -e "${GREEN}✓${NC} go vet passed"
    else
        echo -e "${RED}✗${NC} go vet failed"
        cat /tmp/hook-output.txt
        FAILED=1
    fi

    # 3. Run golangci-lint
    echo -e "${YELLOW}▶${NC} Running golangci-lint..."
    if make lint-go > /tmp/hook-output.txt 2>&1; then
        echo -e "${GREEN}✓${NC} golangci-lint passed"
    else
        echo -e "${RED}✗${NC} golangci-lint failed"
        cat /tmp/hook-output.txt
        FAILED=1
    fi

    # 4. Run gosec (high-severity security scan) — sprung here so findings
    #    surface at commit time, not only at pre-push.
    echo -e "${YELLOW}▶${NC} Running gosec (security scan)..."
    if make gosec > /tmp/hook-output.txt 2>&1; then
        echo -e "${GREEN}✓${NC} gosec passed"
    else
        echo -e "${RED}✗${NC} gosec failed"
        cat /tmp/hook-output.txt
        FAILED=1
    fi
fi

# Markdown checks (only if .md files are staged)
if [ -n "$HAS_MD_FILES" ]; then
    echo -e "${YELLOW}▶${NC} Running markdownlint..."
    if make lint-md > /tmp/hook-output.txt 2>&1; then
        echo -e "${GREEN}✓${NC} markdownlint passed"
    else
        echo -e "${RED}✗${NC} markdownlint failed"
        cat /tmp/hook-output.txt
        FAILED=1
    fi
fi

# TypeScript checks (only if .ts/.tsx files are staged)
if [ -n "$HAS_TS_FILES" ]; then
    echo -e "${YELLOW}▶${NC} Running ESLint (TypeScript)..."
    if (cd web && pnpm lint) > /tmp/hook-output.txt 2>&1; then
        echo -e "${GREEN}✓${NC} ESLint passed"
    else
        echo -e "${RED}✗${NC} ESLint failed"
        cat /tmp/hook-output.txt
        FAILED=1
    fi

    echo -e "${YELLOW}▶${NC} Running TypeScript type check (tsc --noEmit)..."
    if make tsc > /tmp/hook-output.txt 2>&1; then
        echo -e "${GREEN}✓${NC} TypeScript type check passed"
    else
        echo -e "${RED}✗${NC} TypeScript type check failed"
        cat /tmp/hook-output.txt
        FAILED=1
    fi
fi

echo ""
echo -e "${BLUE}╔═══════════════════════════════════════════════════╗${NC}"
if [ $FAILED -eq 0 ]; then
    echo -e "${BLUE}║${NC}  ${GREEN}${BOLD}✓ ALL CHECKS PASSED!${NC}                             ${BLUE}║${NC}"
    echo -e "${BLUE}╚═══════════════════════════════════════════════════╝${NC}"
    exit 0
else
    echo -e "${BLUE}║${NC}  ${RED}${BOLD}✗ CHECKS FAILED${NC}                                  ${BLUE}║${NC}"
    echo -e "${BLUE}╚═══════════════════════════════════════════════════╝${NC}"
    echo -e "${YELLOW}Fix the issues above or use --no-verify to skip${NC}"
    exit 1
fi
