"""Sitemule Blueprint MCP Server.

Provides IBM i program analysis tools via the Model Context Protocol (MCP).
Supports both STDIO and Streamable HTTP transports.
"""

import json
import logging
import time

import httpx
from fastmcp import FastMCP

from .config import settings

# --- Logging ---

# All log output goes to stderr so it never interferes with the MCP
# protocol on stdout.  VS Code surfaces stderr in the MCP output channel.
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(name)s] %(message)s",
    datefmt="%H:%M:%S",
)
logger = logging.getLogger("blueprint")

# --- Server Setup ---

mcp = FastMCP(
    name="blueprint",
    instructions=(
        "Sitemule Blueprint MCP Server for IBM i program analysis. "
        "Use the available tools to explore program call chains, "
        "view source code, and search the source repository."
    ),
)


# --- API Client ---


async def fetch_data(func: str, **kwargs: str | int | None) -> str:
    """Fetch data from the Blueprint API.

    Sends ``func`` plus any additional keyword arguments as query parameters.
    The API key is injected as a header if configured.
    This is internal plumbing; the API key is never exposed to the LLM.

    Returns the response body as a pretty-printed JSON string.
    """
    params: dict[str, str | int] = {"func": func}
    for key, value in kwargs.items():
        if value is not None and value != "":
            params[key] = value

    headers: dict[str, str] = {}
    if settings.api_key:
        headers["Authorization"] = f"Bearer {settings.api_key}"

    logger.info("API request: %s %s", func, {k: v for k, v in kwargs.items() if v is not None})
    t0 = time.monotonic()

    try:
        async with httpx.AsyncClient(timeout=60.0) as client:
            response = await client.get(
                settings.api_base_url,
                params=params,
                headers=headers,
            )
            response.raise_for_status()
            elapsed = time.monotonic() - t0
            logger.info("API response: %s → %s (%.1fs)", func, response.status_code, elapsed)
            return json.dumps(response.json(), indent=2)
    except httpx.HTTPStatusError as exc:
        elapsed = time.monotonic() - t0
        logger.error("API error: %s → HTTP %s (%.1fs)", func, exc.response.status_code, elapsed)
        return json.dumps(
            {
                "error": True,
                "message": f"HTTP {exc.response.status_code} from {settings.api_base_url}",
                "details": exc.response.text[:500],
            },
            indent=2,
        )
    except Exception as exc:
        elapsed = time.monotonic() - t0
        logger.error("API error: %s → %s (%.1fs)", func, exc, elapsed)
        return json.dumps(
            {
                "error": True,
                "message": f"Failed to fetch data from {settings.api_base_url}?func={func}",
                "details": str(exc),
            },
            indent=2,
        )

