#!/usr/bin/env python3
"""
Test de Velocidad: Manual vs Everything3 API
Comparación de rendimiento entre búsqueda manual y Everything API
"""

import os
import sys
import time
import json
import logging
from pathlib import Path
from typing import List

# Configurar logging
logging.basicConfig(
    level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)

# Agregar src al path
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src"))

from utils.everything3_official_corrected_wrapper import (
    create_everything3_official_searcher,
)


def load_config():
    """Cargar configuración"""
    try:
        with open("config.json", "r") as f:
            return json.load(f)
    except Exception as e:
        logger.error(f"Error cargando config: {e}")
        return None


def manual_search_s7p_files(directories: List[str]) -> List[str]:
    """
    Búsqueda manual de archivos .s7p (simulando el fallback)
    """
    found_files = []

    for directory in directories:
        if not os.path.exists(directory):
            continue

        try:
            # Usar Path.rglob para búsqueda recursiva
            path_obj = Path(directory)
            for s7p_file in path_obj.rglob("*.s7p"):
                found_files.append(str(s7p_file))
        except Exception as e:
            logger.error(f"Error buscando en {directory}: {e}")

    return found_files


def everything3_search_s7p_files(directories: List[str], dll_path: str) -> List[str]:
    """
    Búsqueda usando Everything3 API
    """
    searcher = create_everything3_official_searcher(dll_path)
    if not searcher:
        return []

    return searcher.search_s7p_files(directories)


def run_speed_test():
    """Ejecutar test de velocidad completo"""
    print("🏁 Test de Velocidad: Manual vs Everything3 API")
    print("=" * 60)

    # Cargar configuración
    config = load_config()
    if not config:
        print("❌ No se pudo cargar la configuración")
        return

    # Obtener configuraciones
    everything_config = config.get("everything_api", {})
    dll_path = everything_config.get("dll_path")
    if not dll_path:
        print("❌ No se encontró ruta de DLL en configuración")
        return

    # Convertir a ruta absoluta
    if not os.path.isabs(dll_path):
        dll_path = os.path.abspath(dll_path)

    # Obtener directorios de búsqueda
    search_directories = [
        obs_dir["path"]
        for obs_dir in config.get("observation_directories", [])
        if obs_dir.get("enabled", True)
    ]

    print(f"📂 Directorios a analizar: {len(search_directories)}")
    for i, directory in enumerate(search_directories, 1):
        print(f"  {i}. {directory}")

    print(f"📁 DLL Everything3: {dll_path}")
    print()

    # Variables para resultados
    results = {}

    # ========================================
    # TEST 1: Búsqueda Manual (Fallback)
    # ========================================
    print("🔍 TEST 1: Búsqueda Manual (Fallback)")
    print("-" * 40)

    start_time = time.perf_counter()
    manual_files = manual_search_s7p_files(search_directories)
    manual_time = time.perf_counter() - start_time

    print(f"⏱️  Tiempo: {manual_time:.4f} segundos")
    print(f"📊 Archivos encontrados: {len(manual_files)}")

    results["manual"] = {
        "time": manual_time,
        "files_found": len(manual_files),
        "files": manual_files,
    }

    print()

    # ========================================
    # TEST 2: Everything3 API
    # ========================================
    print("🚀 TEST 2: Everything3 API")
    print("-" * 40)

    start_time = time.perf_counter()
    everything_files = everything3_search_s7p_files(search_directories, dll_path)
    everything_time = time.perf_counter() - start_time

    print(f"⏱️  Tiempo: {everything_time:.4f} segundos")
    print(f"📊 Archivos encontrados: {len(everything_files)}")

    results["everything3"] = {
        "time": everything_time,
        "files_found": len(everything_files),
        "files": everything_files,
    }

    print()

    # ========================================
    # COMPARACIÓN DE RESULTADOS
    # ========================================
    print("📈 COMPARACIÓN DE RESULTADOS")
    print("=" * 60)

    # Velocidad
    if manual_time > 0:
        speed_improvement = manual_time / everything_time
        print(f"⚡ Everything3 es {speed_improvement:.2f}x más rápido")

        time_saved = manual_time - everything_time
        percentage_faster = ((manual_time - everything_time) / manual_time) * 100
        print(
            f"💾 Tiempo ahorrado: {time_saved:.4f} segundos ({percentage_faster:.1f}%)"
        )

    print()

    # Precisión
    manual_set = set(os.path.normpath(f) for f in manual_files)
    everything_set = set(os.path.normpath(f) for f in everything_files)

    # Archivos en común
    common_files = manual_set & everything_set
    print(f"🎯 Archivos encontrados por ambos: {len(common_files)}")

    # Archivos solo en manual
    only_manual = manual_set - everything_set
    if only_manual:
        print(f"📁 Solo en búsqueda manual: {len(only_manual)}")
        for file in only_manual:
            print(f"     - {file}")

    # Archivos solo en Everything3
    only_everything = everything_set - manual_set
    if only_everything:
        print(f"🚀 Solo en Everything3: {len(only_everything)}")
        for file in only_everything:
            print(f"     - {file}")

    # Exactitud
    if len(manual_files) > 0:
        accuracy = (
            len(common_files) / max(len(manual_files), len(everything_files))
        ) * 100
        print(f"✅ Exactitud: {accuracy:.1f}%")

    print()

    # ========================================
    # RESUMEN EJECUTIVO
    # ========================================
    print("📋 RESUMEN EJECUTIVO")
    print("=" * 60)

    print(f"🔍 Búsqueda Manual:")
    print(f"   ⏱️  Tiempo: {manual_time:.4f}s")
    print(f"   📊 Archivos: {len(manual_files)}")

    print(f"🚀 Everything3 API:")
    print(f"   ⏱️  Tiempo: {everything_time:.4f}s")
    print(f"   📊 Archivos: {len(everything_files)}")

    print(f"📈 Mejora de rendimiento:")
    if manual_time > 0:
        print(f"   ⚡ {speed_improvement:.2f}x más rápido")
        print(f"   💾 {time_saved:.4f}s ahorrados ({percentage_faster:.1f}%)")

    # Recomendación
    print()
    print("💡 RECOMENDACIÓN:")
    if everything_time < manual_time and len(everything_files) >= len(manual_files):
        print("✅ Usar Everything3 API - Mejor rendimiento y precisión")
    elif everything_time < manual_time:
        print("⚖️  Everything3 API es más rápido pero revisa la precisión")
    else:
        print("⚠️  Evaluar caso por caso - Manual puede ser más confiable")

    return results


def run_multiple_tests(iterations: int = 3):
    """Ejecutar múltiples tests para obtener promedio"""
    print(f"🔬 Ejecutando {iterations} iteraciones para obtener promedio...")
    print()

    manual_times = []
    everything_times = []

    for i in range(iterations):
        print(f"📊 Iteración {i+1}/{iterations}")
        results = run_speed_test()

        if results:
            manual_times.append(results["manual"]["time"])
            everything_times.append(results["everything3"]["time"])

        print()
        print("-" * 80)
        print()

    # Calcular promedios
    if manual_times and everything_times:
        avg_manual = sum(manual_times) / len(manual_times)
        avg_everything = sum(everything_times) / len(everything_times)

        print("📊 PROMEDIO DE MÚLTIPLES TESTS")
        print("=" * 60)
        print(f"🔍 Manual promedio: {avg_manual:.4f}s")
        print(f"🚀 Everything3 promedio: {avg_everything:.4f}s")

        if avg_manual > 0:
            avg_improvement = avg_manual / avg_everything
            print(f"⚡ Everything3 es {avg_improvement:.2f}x más rápido en promedio")


if __name__ == "__main__":
    try:
        # Test único
        run_speed_test()

        print("\n" + "=" * 80 + "\n")

        # Test múltiple para promedio
        run_multiple_tests(3)

    except KeyboardInterrupt:
        print("\n⏸️  Test interrumpido por el usuario")
    except Exception as e:
        logger.error(f"Error en test de velocidad: {e}")
        print(f"❌ Error en test: {e}")
