import logging
import os
import subprocess
import sys
import tempfile

from mcp.server.fastmcp import FastMCP

logger = logging.getLogger(__name__)
logging.basicConfig(stream=sys.stderr, level=logging.INFO)

DEFAULT_TIMEOUT = 120

LEAN_PROJECT_PATH = os.environ.get("LEAN_PROJECT_PATH", "")

mcp = FastMCP("lean4-formal-verifier")


def _resolve_project_path() -> str:
    path = LEAN_PROJECT_PATH
    if not path:
        path = os.getcwd()
        logger.info("LEAN_PROJECT_PATH nao definido, usando diretorio atual: %s", path)
    if not os.path.isdir(path):
        raise FileNotFoundError(f"Diretorio do projeto Lean nao encontrado: {path}")
    return path


@mcp.tool()
def verify_lean_theorem(lean_code: str, timeout: int = DEFAULT_TIMEOUT) -> str:
    """Compila codigo Lean 4 com Mathlib e retorna o resultado.

    Retorna '[QED]' se a prova compila sem erros (returncode 0, sem output).
    Retorna '[FEEDBACK DO COMPILADOR]' seguido do output em caso de erro.
    Retorna '[ERRO_SISTEMA]' em caso de falha de infraestrutura.

    Args:
        lean_code: Bloco de codigo Lean 4 completo (incluindo imports).
        timeout: Timeout em segundos para compilacao (padrao: 120).
    """
    project_path = _resolve_project_path()

    with tempfile.NamedTemporaryFile(mode="w", suffix=".lean", delete=False, encoding="utf-8") as f:
        if not lean_code.strip().startswith("import"):
            f.write("import Mathlib\n\n")
        f.write(lean_code)
        temp_path = f.name

    try:
        result = subprocess.run(
            ["lake", "env", "lean", temp_path],
            capture_output=True,
            text=True,
            cwd=project_path,
            timeout=timeout,
        )

        output = (result.stdout + result.stderr).strip()

        if result.returncode == 0 and not output:
            return "[QED] Compilacao bem-sucedida. Nenhum erro. Prova completa."

        return f"[FEEDBACK DO COMPILADOR]\n{output}"

    except subprocess.TimeoutExpired:
        return f"[ERRO_SISTEMA] Compilacao excedeu o limite de {timeout}s."
    except FileNotFoundError:
        return (
            "[ERRO_SISTEMA] Executavel 'lake' nao encontrado. "
            "Verifique se Elan/Lean esta instalado e no PATH."
        )
    except Exception as e:
        return f"[ERRO_SISTEMA] Falha na execucao: {e}"
    finally:
        try:
            os.remove(temp_path)
        except OSError:
            logger.warning("Nao foi possivel remover %s", temp_path)


def main() -> None:
    mcp.run(transport="stdio")


if __name__ == "__main__":
    main()
