#!/bin/bash
# Pre-commit hook: ejecuta clang-format y clang-tidy en archivos modificados
# Para instalarlo: cp tools/hooks/pre-commit .git/hooks/ && chmod +x .git/hooks/pre-commit
# O ejecuta: tools/hooks/install.sh

set -e  # Salir si hay error

echo "🔍 Pre-commit hook: verificando código..."

# Obtener raíz del repositorio
REPO_ROOT=$(git rev-parse --show-toplevel)

# Obtener archivos staged (solo .cpp y .hpp)
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM | grep -E '\.(cpp|hpp)$' || true)

if [ -z "$STAGED_FILES" ]; then
    echo "✅ No hay archivos C++ para revisar"
    exit 0
fi

# Excluir directorios audio/ y legacy/ (igual que CMakeLists.txt)
FILTERED_FILES=""
for file in $STAGED_FILES; do
    # Excluir si está en audio/ o legacy/
    if [[ ! "$file" =~ audio/ ]] && [[ ! "$file" =~ legacy/ ]]; then
        # Solo incluir si el archivo existe (no fue eliminado)
        if [ -f "$file" ]; then
            FILTERED_FILES="$FILTERED_FILES $file"
        fi
    fi
done

if [ -z "$FILTERED_FILES" ]; then
    echo "✅ No hay archivos C++ para revisar (excluidos audio/ y legacy/)"
    exit 0
fi

echo "📝 Archivos a revisar:$FILTERED_FILES"

# ============================================
# PASO 1: Ejecutar clang-format (auto-format)
# ============================================
echo ""
echo "🎨 Ejecutando clang-format..."

FORMAT_CHANGED=false
for file in $FILTERED_FILES; do
    # Ejecutar clang-format in-place
    clang-format --style=file -i "$file"

    # Verificar si el archivo cambió
    if ! git diff --quiet "$file"; then
        echo "  ✏️  Formateado: $file"
        FORMAT_CHANGED=true
        # Añadir cambios de formato al staging
        git add "$file"
    fi
done

if [ "$FORMAT_CHANGED" = true ]; then
    echo "✅ Archivos formateados automáticamente y añadidos al commit"
else
    echo "✅ Formato correcto (sin cambios)"
fi

# ============================================
# PASO 2: Ejecutar clang-tidy (verificación)
# ============================================
echo ""
echo "🔍 Ejecutando clang-tidy..."

# Configurar SDK de macOS (igual que CMakeLists.txt)
MACOS_SDK=$(xcrun --show-sdk-path 2>/dev/null || echo "")

TIDY_FAILED=false
TIDY_OUTPUT=""

for file in $FILTERED_FILES; do
    # Ejecutar clang-tidy con configuración del proyecto
    if [ -n "$MACOS_SDK" ]; then
        TIDY_RESULT=$(clang-tidy "$file" \
            --extra-arg=-std=c++20 \
            --extra-arg=-isysroot"$MACOS_SDK" \
            --extra-arg=-I"$REPO_ROOT"/source \
            --extra-arg=-I"$REPO_ROOT"/build \
            -- 2>&1 || echo "TIDY_ERROR")
    else
        TIDY_RESULT=$(clang-tidy "$file" \
            --extra-arg=-std=c++20 \
            --extra-arg=-I"$REPO_ROOT"/source \
            --extra-arg=-I"$REPO_ROOT"/build \
            -- 2>&1 || echo "TIDY_ERROR")
    fi

    # Verificar si hubo errores (ignorar warnings de headers del sistema)
    ERROR_COUNT=$(echo "$TIDY_RESULT" | grep -E "error:|warning:" | grep -v "in non-user code" | wc -l | tr -d ' ')

    if [ "$ERROR_COUNT" -gt 0 ]; then
        TIDY_FAILED=true
        TIDY_OUTPUT="$TIDY_OUTPUT\n\n❌ Errores en $file:\n$TIDY_RESULT"
    else
        echo "  ✅ $file"
    fi
done

# Si clang-tidy encontró errores, bloquear commit
if [ "$TIDY_FAILED" = true ]; then
    echo ""
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo "❌ COMMIT BLOQUEADO: clang-tidy encontró errores"
    echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
    echo -e "$TIDY_OUTPUT"
    echo ""
    echo "💡 Soluciones:"
    echo "  1. Corrige los errores manualmente"
    echo "  2. O ejecuta: make tidy (aplica fixes automáticos)"
    echo "  3. Luego: git add <archivos> && git commit"
    echo ""
    echo "⚠️  Si necesitas saltarte el hook (NO RECOMENDADO):"
    echo "  git commit --no-verify"
    echo ""
    exit 1
fi

echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ Pre-commit hook: TODO OK"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "  🎨 clang-format: OK (archivos formateados)"
echo "  🔍 clang-tidy: OK (sin errores)"
echo ""

exit 0
