#!/bin/bash

# Script para ejecutar clang-tidy recursivamente en todo el código fuente
# Uso:
#   ./run_clang-tidy.sh [--fix] [--help] [archivos...]
# --fix: Aplica las correcciones automáticamente (opcional)
# --help: Muestra la ayuda
# archivos: Archivos específicos a analizar (opcional, si no se especifica analiza todos)

# Función de ayuda
show_help() {
    cat << EOF
Uso: ./run_clang-tidy.sh [OPCIONES] [ARCHIVOS...]

Script para ejecutar clang-tidy en el código fuente del proyecto.

OPCIONES:
    --fix       Aplica las correcciones automáticamente
    --help      Muestra este mensaje de ayuda

ARCHIVOS:
    Si no se especifican archivos, se analizan todos los archivos del proyecto
    (excluyendo la carpeta external/ y jail_audio.hpp). Si se especifican archivos,
    solo se analizan esos archivos específicos.

EJEMPLOS:
    # Analizar todo el proyecto
    ./run_clang-tidy.sh

    # Analizar todo el proyecto y aplicar correcciones
    ./run_clang-tidy.sh --fix

    # Analizar un archivo específico
    ./run_clang-tidy.sh source/game/entities/enemy.cpp

    # Analizar múltiples archivos
    ./run_clang-tidy.sh source/game/entities/enemy.cpp source/game/entities/player.cpp

    # Analizar y corregir un archivo específico
    ./run_clang-tidy.sh --fix source/game/entities/enemy.cpp

    # Analizar todos los archivos de una carpeta (usando glob)
    ./run_clang-tidy.sh source/game/entities/*.cpp

NOTAS:
    - Se requiere que el directorio build/ exista y contenga compile_commands.json
    - Los archivos se procesan en paralelo (4 procesos)
    - Solo se procesan archivos .cpp, .hpp y .h
    - Las rutas pueden ser relativas o absolutas

EOF
    exit 0
}

# Auto-detectar la ubicación del script y calcular rutas del proyecto
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
PROJECT_DIR=$(cd "$SCRIPT_DIR/../.." && pwd)
SOURCE_DIR="$PROJECT_DIR/source"
BUILD_DIR="$PROJECT_DIR/build"

# Parsear argumentos: separar --fix, --help de archivos
FIX_FLAG=""
FILES=()

for arg in "$@"; do
    if [[ "$arg" == "--fix" ]]; then
        FIX_FLAG="--fix"
    elif [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
        show_help
    else
        FILES+=("$arg")
    fi
done

# Mostrar modo
if [[ -n "$FIX_FLAG" ]]; then
    echo "Modo: Aplicando correcciones automáticamente (--fix)"
else
    echo "Modo: Solo análisis (sin --fix)"
fi
echo

# Verificar que los directorios existen
if [[ ! -d "$SOURCE_DIR" ]]; then
    echo "Error: El directorio source/ no existe en: $SOURCE_DIR"
    exit 1
fi

if [[ ! -d "$BUILD_DIR" ]]; then
    echo "Error: El directorio build/ no existe en: $BUILD_DIR"
    echo "Ejecuta primero: cmake -B build && cmake --build build"
    exit 1
fi

echo "Proyecto: $PROJECT_DIR"
echo "Fuentes: $SOURCE_DIR"
echo "Build: $BUILD_DIR"
echo

# Si se especificaron archivos, procesarlos directamente
if [[ ${#FILES[@]} -gt 0 ]]; then
    echo "=== Procesando ${#FILES[@]} archivo(s) específico(s) ==="

    # Validar y procesar cada archivo
    VALID_FILES=()
    for file in "${FILES[@]}"; do
        # Convertir a ruta absoluta si es relativa
        if [[ ! "$file" = /* ]]; then
            file="$PROJECT_DIR/$file"
        fi

        # Verificar que existe
        if [[ ! -f "$file" ]]; then
            echo "Advertencia: Archivo no encontrado: $file (omitiendo)"
            continue
        fi

        # Verificar extensión
        if [[ "$file" =~ \.(cpp|hpp|h)$ ]]; then
            VALID_FILES+=("$file")
        else
            echo "Advertencia: Archivo no es C++: $file (omitiendo)"
        fi
    done

    # Si no hay archivos válidos, salir
    if [[ ${#VALID_FILES[@]} -eq 0 ]]; then
        echo "Error: No hay archivos válidos para procesar"
        exit 1
    fi

    echo
    # Procesar archivos en paralelo
    printf '%s\n' "${VALID_FILES[@]}" | \
    xargs -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p '"$BUILD_DIR"' '"$FIX_FLAG"

    echo
    echo "¡Proceso completado para ${#VALID_FILES[@]} archivo(s)!"
else
    # Comportamiento original: procesar todos los archivos
    echo "=== Escaneando recursivamente source/ (excluyendo external/ y jail_audio.hpp) ==="
    find "$SOURCE_DIR" \( -name '*.cpp' -o -name '*.h' -o -name '*.hpp' \) -not -path "*/external/*" -not -path "*/core/audio/jail_audio.hpp" -not -name '*_spv.h' -print0 | \
    xargs -0 -P4 -I{} bash -c 'echo "Procesando: {}"; clang-tidy {} -p '"$BUILD_DIR"' '"$FIX_FLAG"

    echo
    echo "¡Proceso completado para todos los archivos!"
fi
