"""
Herramienta de diagnóstico para problemas con WinFSP y montaje FUSE en Windows.
Ejecutar este script como administrador para obtener mejores resultados.
"""

import sys
import os

# Asegurar que el entorno virtual esté en sys.path
venv_site_packages = os.path.abspath(os.path.join(os.path.dirname(__file__), ".venv", "Lib", "site-packages"))
if venv_site_packages not in sys.path:
    sys.path.insert(0, venv_site_packages)

# Forzar la inclusión de rutas adicionales
if r"C:\contenedor_cuantico_1\.venv\Lib\site-packages" not in sys.path:
    sys.path.insert(0, r"C:\contenedor_cuantico_1\.venv\Lib\site-packages")

import subprocess
import ctypes
import winreg
import platform
import datetime  # Añadido para manejar fechas sin problemas de codificación
from module_utils import find_module_path

def is_admin():
    """Verifica si el script se está ejecutando con privilegios de administrador."""
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

def check_winfsp_installation():
    """Verifica si WinFSP está instalado correctamente."""
    print("\n=== Verificando instalación de WinFSP ===")
    
    # Verificar registro de Windows para WinFSP
    try:
        key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\WOW6432Node\WinFsp")
        version = winreg.QueryValueEx(key, "Version")[0]
        install_dir = winreg.QueryValueEx(key, "InstallDir")[0]
        print(f"✓ WinFSP instalado: Versión {version}")
        print(f"✓ Directorio de instalación: {install_dir}")
        
        # Verificar existencia de archivos clave
        dll_path = os.path.join(install_dir, "bin", "winfsp-x64.dll")
        if os.path.exists(dll_path):
            print(f"✓ Biblioteca principal encontrada: {dll_path}")
        else:
            print(f"✗ Biblioteca principal NO encontrada: {dll_path}")
            
        launcher_path = os.path.join(install_dir, "bin", "launchctl-x64.exe")
        if os.path.exists(launcher_path):
            print(f"✓ Launcher encontrado: {launcher_path}")
        else:
            print(f"✗ Launcher NO encontrado: {launcher_path}")
            
    except FileNotFoundError:
        print("✗ WinFSP no está registrado en el sistema.")
        print("  Descargue e instale WinFSP desde: https://github.com/winfsp/winfsp/releases")
        return False
    except Exception as e:
        print(f"✗ Error al verificar instalación de WinFSP: {e}")
        return False
    
    return True

def check_python_modules():
    """Verifica si los módulos de Python necesarios están instalados."""
    print("\n=== Verificando módulos de Python ===")
    print("DEBUG: Rutas en sys.path:")
    print("\n".join(sys.path))  # Imprimir las rutas en sys.path para depuración

    required_modules = ["fusepy", "zstd", "numpy", "Pillow", "anytree"]
    missing_modules = []

    for module in required_modules:
        try:
            # Intentar importar el módulo
            imported_module = __import__(module)
            print(f"✓ Módulo {module} encontrado en: {imported_module.__file__}")
        except ImportError as e:
            print(f"✗ Módulo {module} NO encontrado: {e}")
            module_path = find_module_path(module, venv_site_packages)
            if module_path:
                sys.path.insert(0, module_path)
                try:
                    imported_module = __import__(module)
                    print(f"✓ Módulo {module} importado correctamente después de ajustar sys.path")
                except ImportError as e:
                    print(f"✗ Error al importar {module} incluso después de ajustar sys.path: {e}")
                    missing_modules.append(module)
            else:
                missing_modules.append(module)

    if missing_modules:
        print("\nInstale los módulos faltantes con:")
        print(f"pip install {' '.join(missing_modules)}")
        return False

    return True

def check_mountpoint_status(mountpoint):
    """Verifica el estado del punto de montaje."""
    print(f"\n=== Verificando punto de montaje: {mountpoint} ===")
    
    if not os.path.exists(mountpoint):
        print(f"✗ El punto de montaje no existe")
        return False
    
    # Verificar permisos
    try:
        test_file = os.path.join(mountpoint, "test_write.tmp")
        with open(test_file, 'w') as f:
            f.write("test")
        os.remove(test_file)
        print("✓ Permisos de escritura correctos")
    except PermissionError:
        print("✗ Sin permisos de escritura en el punto de montaje")
        return False
    except Exception as e:
        print(f"✗ Error al probar permisos: {e}")
        return False
    
    # Verificar uso por otros procesos
    try:
        result = subprocess.run(["handle", mountpoint], 
                              capture_output=True, text=True, timeout=5)
        if mountpoint.lower() in result.stdout.lower():
            print("✗ El punto de montaje está siendo usado por otros procesos:")
            for line in result.stdout.splitlines():
                if mountpoint.lower() in line.lower():
                    print(f"  {line.strip()}")
        else:
            print("✓ El punto de montaje no está siendo usado por otros procesos")
    except FileNotFoundError:
        print("ℹ️ Herramienta 'handle' no encontrada. No se puede verificar el uso por otros procesos.")
        print("  Descargue desde: https://docs.microsoft.com/en-us/sysinternals/downloads/handle")
    except Exception as e:
        print(f"ℹ️ Error al verificar uso del punto de montaje: {e}")
    
    return True

def run_winfsp_info():
    """Ejecuta winfsp-tests-x64.exe info para ver información sobre WinFSP."""
    print("\n=== Información de WinFSP ===")
    
    try:
        result = subprocess.run(["C:\\Program Files (x86)\\WinFsp\\bin\\winfsp-tests-x64.exe", "info"], 
                              capture_output=True, text=True, timeout=5)
        if result.returncode == 0:
            print(result.stdout)
        else:
            print(f"✗ Error al ejecutar prueba de WinFSP: {result.stderr}")
    except FileNotFoundError:
        print("✗ No se encontró winfsp-tests-x64.exe")
    except Exception as e:
        print(f"✗ Error al ejecutar información de WinFSP: {e}")

def fix_mountpoint_problems(mountpoint):
    """Intenta solucionar problemas comunes del punto de montaje."""
    print("\n=== Intentando solucionar problemas ===")
    
    # Intentar desmontar con net use
    try:
        subprocess.run(["net", "use", mountpoint, "/DELETE", "/Y"], 
                      capture_output=True, text=True, timeout=5)
        print("✓ Punto de montaje desmontado con net use")
    except Exception as e:
        print(f"ℹ️ No se pudo desmontar con net use: {e}")
    
    # Vaciar el directorio (si existe)
    if os.path.exists(mountpoint):
        try:
            for item in os.listdir(mountpoint):
                item_path = os.path.join(mountpoint, item)
                if os.path.isfile(item_path):
                    os.unlink(item_path)
                # No eliminar subdirectorios por seguridad
            print("✓ Archivos eliminados del punto de montaje")
        except Exception as e:
            print(f"✗ Error al limpiar el punto de montaje: {e}")
    
    print("\nAcciones recomendadas:")
    print("1. Cierre todas las ventanas del Explorador que tengan abierto el punto de montaje")
    print("2. Reinicie el servicio WinFSP usando el comando 'net stop WinFsp.Launcher' y 'net start WinFsp.Launcher'")
    print("3. Asegúrese de ejecutar el programa como administrador")
    print("4. Reinicie el equipo si el problema persiste")

def check_system_compatibility():
    """Verifica si el sistema es compatible con WinFSP."""
    print("\n=== Verificando compatibilidad del sistema ===")
    
    # Verificar sistema operativo
    win_ver = platform.win32_ver()
    print(f"Sistema operativo: Windows {win_ver[0]} {win_ver[1]}")
    
    # Verificar si es 32 o 64 bits
    arch = platform.architecture()[0]
    print(f"Arquitectura: {arch}")
    if arch == "32bit":
        print("⚠️ WinFSP funciona mejor en sistemas de 64 bits")
    
    # Verificar si el servicio WinFSP.Launcher está en ejecución
    try:
        result = subprocess.run(["sc", "query", "WinFsp.Launcher"], 
                              capture_output=True, text=True, timeout=5)
        if "RUNNING" in result.stdout:
            print("✓ Servicio WinFSP.Launcher en ejecución")
        else:
            print("✗ Servicio WinFSP.Launcher NO está en ejecución")
            print("  Inicie el servicio con: net start WinFsp.Launcher")
    except Exception as e:
        print(f"ℹ️ Error al verificar el servicio WinFSP.Launcher: {e}")

def main():
    if not is_admin():
        print("⚠️ Este script no se está ejecutando como administrador.")
        print("   Algunos diagnósticos podrían fallar por falta de permisos.")
        print("   Se recomienda ejecutar como administrador para mejores resultados.\n")
    
    print("=== Diagnóstico de WinFSP y Sistema de Archivos FUSE ===")
    # Usar datetime en lugar de subprocess para evitar problemas de codificación
    now = datetime.datetime.now()
    print(f"Fecha y hora: {now.strftime('%d/%m/%Y %H:%M:%S')}")
    
    # Verificar instalación de WinFSP
    winfsp_ok = check_winfsp_installation()
    
    # Verificar módulos de Python
    modules_ok = check_python_modules()
    
    # Verificar punto de montaje
    mountpoint = os.path.join(os.path.dirname(os.path.dirname(__file__)), "mountpoint")
    mountpoint_ok = check_mountpoint_status(mountpoint)
    
    # Ejecutar información de WinFSP
    if winfsp_ok:
        run_winfsp_info()
    
    # Verificar compatibilidad del sistema
    check_system_compatibility()
    
    # Intentar solucionar problemas
    if not mountpoint_ok:
        fix_mountpoint_problems(mountpoint)
    
    print("\n=== Resumen del diagnóstico ===")
    print(f"WinFSP instalación: {'✓ OK' if winfsp_ok else '✗ Problema'}")
    print(f"Módulos Python: {'✓ OK' if modules_ok else '✗ Problema'}")
    print(f"Punto de montaje: {'✓ OK' if mountpoint_ok else '✗ Problema'}")
    
    print("\n=== Siguientes pasos ===")
    if winfsp_ok and modules_ok and mountpoint_ok:
        print("Todo parece estar configurado correctamente. Pruebe lo siguiente:")
        print("1. Ejecute el programa Contenedor Cuántico como administrador")
        print("2. Si persisten los problemas, reinicie el equipo y pruebe de nuevo")
    else:
        print("Solucione los problemas identificados y ejecute este diagnóstico nuevamente.")
    
    print("\nPara más información, consulte la documentación de WinFSP:")
    print("https://github.com/winfsp/winfsp/wiki/WinFsp-Tutorial")

if __name__ == "__main__":
    main()
