"""FastMCP server skeleton with structured_tool_handler catch-all decorator."""

from __future__ import annotations

import functools
import logging
from typing import Any

from mcp.server.fastmcp import FastMCP

from .config import load_config
from .models import ErrorDetail, ToolResult

logger = logging.getLogger("vmcluster_mcp")

config = load_config()
mcp = FastMCP("vmcluster-mcp")


def structured_tool_handler(func):
    """Catch-all decorator ensuring every tool returns ToolResult, never a raw exception.

    Per design doc section 2.8: all tool exits must be ToolResult.
    Exception leakage from tool handlers is a contract violation.
    """

    @functools.wraps(func)
    async def wrapper(*args: Any, **kwargs: Any) -> ToolResult:
        try:
            return await func(*args, **kwargs)
        except Exception as e:
            logger.exception("Tool handler %s raised %s", func.__name__, type(e).__name__)
            return ToolResult(
                success=False,
                result=None,
                error=ErrorDetail(
                    code="INTERNAL_ERROR",
                    message=f"{type(e).__name__}: {e}",
                    node=None,
                    recoverable=False,
                ),
            )

    return wrapper


from vmcluster_mcp import (  # noqa: E402, F401 — must follow mcp definition; triggers tool registration
    artifact,
    cluster,
    exec,
    net,
    observe,
    snapshot,
)

if __name__ == "__main__":
    mcp.run()
