# server_runner.py
import subprocess
import asyncio
import socket
import re
from pathlib import Path

async def wait_for_port(host: str, port: int, timeout: float = 10.0):
    for _ in range(int(timeout * 10)):
        try:
            with socket.create_connection((host, port), timeout=0.5):
                return True
        except (OSError, ConnectionRefusedError):
            await asyncio.sleep(0.1)
    raise TimeoutError(f"No se pudo conectar al servidor en {host}:{port}")

class MCPServerRunner:
    def __init__(self, server_script_path: str, python_path: str = "python"):
        self.server_script_path = server_script_path
        self.python_path = python_path
        self.port: int = self._extraer_puerto()
        self.process: subprocess.Popen | None = None

    def _extraer_puerto(self) -> int:
        contenido = Path(self.server_script_path).read_text(encoding="utf-8")
        coincidencias = re.findall(r"port\s*=\s*(\d+)", contenido)
        if not coincidencias:
            raise ValueError(f"No se pudo detectar el puerto en {self.server_script_path}")
        return int(coincidencias[0])

    async def start(self):
        if self.process is None or self.process.poll() is not None:
            self.process = subprocess.Popen(
                [self.python_path, self.server_script_path],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE
            )
            await wait_for_port("127.0.0.1", self.port)
            print(f"🟢 Servidor MCP iniciado en puerto {self.port}")

    async def stop(self):
        if self.process and self.process.poll() is None:
            self.process.terminate()
            try:
                self.process.wait(timeout=5)
            except subprocess.TimeoutExpired:
                self.process.kill()
            print("🔴 Servidor MCP detenido")