"""
health_check.py - Verificación de salud del sistema
T107-T110: Health checks
"""
import sys
import os
import socket
import json
import logging
from pathlib import Path
from typing import Dict, Any, List

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("HealthCheck")


class AbletonMCPHealthCheck:
    """Verifica la salud del sistema AbletonMCP-AI."""

    def __init__(self):
        self.checks: List[Dict[str, Any]] = []
        self.all_passed = True

    def check_ableton_connection(self) -> bool:
        """Verifica conexión a Ableton Live."""
        try:
            from server import HOST, DEFAULT_PORT
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            sock.settimeout(2)
            result = sock.connect_ex((HOST, DEFAULT_PORT))
            sock.close()

            if result == 0:
                self._add_check("Ableton Connection", True, f"Connected on {HOST}:{DEFAULT_PORT}")
                return True
            else:
                self._add_check("Ableton Connection", False, f"Port {DEFAULT_PORT} not available on {HOST} (code {result})")
                return False
        except Exception as e:
            self._add_check("Ableton Connection", False, str(e))
            return False

    def check_mcp_server(self) -> bool:
        """Verifica que el servidor MCP responde."""
        try:
            # Intentar importar el módulo
            from full_integration import AbletonMCPFullPipeline
            pipeline = AbletonMCPFullPipeline()

            self._add_check("MCP Server", True, "Module imports successfully")
            return True
        except Exception as e:
            self._add_check("MCP Server", False, f"Import error: {e}")
            return False

    def check_sample_library(self) -> bool:
        """Verifica librería de samples."""
        lib_paths = [
            Path("librerias/organized_samples"),  # Primary: organized with subfolders
            Path.home() / "embeddings" / "organized_samples",
            Path("librerias/all_tracks"),  # Fallback: flat structure
            Path.home() / "embeddings" / "all_tracks",
        ]

        for path in lib_paths:
            if path.exists():
                wav_files = list(path.rglob("*.wav"))
                if len(wav_files) > 0:
                    self._add_check("Sample Library", True, f"{len(wav_files)} samples at {path}")
                    return True

        self._add_check("Sample Library", False, "No sample library found")
        return False

    def check_dependencies(self) -> bool:
        """Verifica dependencias de Python."""
        required = [
            'numpy',
            'sklearn',
            'sentence_transformers',
        ]

        missing = []
        for dep in required:
            try:
                __import__(dep)
            except ImportError:
                missing.append(dep)

        if missing:
            self._add_check("Dependencies", False, f"Missing: {', '.join(missing)}")
            return False

        self._add_check("Dependencies", True, "All required packages available")
        return True

    def check_vector_index(self) -> bool:
        """Verifica índice de vectores."""
        index_paths = [
            Path("librerias/organized_samples/.sample_embeddings.json"),  # Primary
            Path.home() / "embeddings" / "organized_samples" / ".sample_embeddings.json",
            Path("librerias/all_tracks/.sample_embeddings.json"),  # Fallback
            Path.home() / "embeddings" / "all_tracks" / ".sample_embeddings.json",
        ]

        for path in index_paths:
            if path.exists():
                self._add_check("Vector Index", True, f"Index at {path}")
                return True

        self._add_check("Vector Index", False, "No index found - will be built on first run")
        return False

    def check_persistence_files(self) -> bool:
        """Verifica archivos de persistencia."""
        data_dir = Path.home() / ".abletonmcp_ai"

        files_to_check = [
            "sample_history.json",
            "sample_fatigue.json",
            "collection_coverage.json",
        ]

        all_ok = True
        for file in files_to_check:
            path = data_dir / file
            if path.exists():
                self._add_check(f"Persistence: {file}", True, "File exists")
            else:
                self._add_check(f"Persistence: {file}", False, "Will be created")
                all_ok = False

        return all_ok

    def check_tests(self) -> bool:
        """Verifica que los tests pasan."""
        try:
            import subprocess
            result = subprocess.run(
                [sys.executable, "-m", "unittest", "tests.test_human_feel", "-v"],
                capture_output=True,
                timeout=30,
                cwd=Path(__file__).parent
            )

            if result.returncode == 0:
                self._add_check("Unit Tests", True, "All tests passing")
                return True
            else:
                self._add_check("Unit Tests", False, "Some tests failed")
                return False
        except Exception as e:
            self._add_check("Unit Tests", False, f"Error running tests: {e}")
            return False

    def _add_check(self, name: str, passed: bool, message: str):
        """Agrega un check al reporte."""
        self.checks.append({
            'name': name,
            'passed': passed,
            'message': message
        })
        if not passed:
            self.all_passed = False

    def run_all_checks(self) -> Dict[str, Any]:
        """Ejecuta todos los checks."""
        logger.info("Running health checks...")
        logger.info("=" * 50)

        self.check_ableton_connection()
        self.check_mcp_server()
        self.check_sample_library()
        self.check_dependencies()
        self.check_vector_index()
        self.check_persistence_files()
        self.check_tests()

        # Summary
        passed = sum(1 for c in self.checks if c['passed'])
        total = len(self.checks)

        logger.info("=" * 50)
        logger.info(f"RESULT: {passed}/{total} checks passed")

        return {
            'all_passed': self.all_passed,
            'passed': passed,
            'total': total,
            'checks': self.checks
        }


def main():
    """Ejecuta health check desde línea de comandos."""
    checker = AbletonMCPHealthCheck()
    result = checker.run_all_checks()

    # Guardar resultado
    output_path = Path("health_check_result.json")
    with open(output_path, 'w') as f:
        json.dump(result, f, indent=2)

    # Exit code
    sys.exit(0 if result['all_passed'] else 1)


if __name__ == '__main__':
    main()
