"""표준 입력/출력 기반 MCP 서버의 진입점."""

from __future__ import annotations

import logging
import os
from importlib.metadata import PackageNotFoundError, version
from pathlib import Path
from typing import Dict, List

import anyio
import mcp.types as types
from mcp.server import NotificationOptions, Server
from mcp.server.stdio import stdio_server

from .hwpx_ops import HwpxOps, HwpxOperationError
from .logging_conf import configure_logging
from .tools import ToolDefinition, build_tool_definitions

LOGGER = logging.getLogger(__name__)
DEFAULT_SERVER_NAME = "hwpx-mcp-server"


def _bool_env(name: str, default: bool = False) -> bool:
    raw = os.getenv(name)
    if raw is None:
        return default
    return raw.strip().lower() in {"1", "true", "yes", "on"}


def _resolve_version() -> str:
    try:
        return version("hwpx-mcp-server")
    except PackageNotFoundError:  # pragma: no cover - local development fallback
        return "0.0.0"


async def _serve(ops: HwpxOps, tools: List[ToolDefinition]) -> None:
    server = Server(DEFAULT_SERVER_NAME, version=_resolve_version())
    tool_map: Dict[str, ToolDefinition] = {tool.name: tool for tool in tools}

    @server.list_tools()
    async def _list_tools() -> List[types.Tool]:  # type: ignore[name-defined]
        return [tool.to_tool() for tool in tools]

    @server.call_tool()
    async def _call_tool(name: str, arguments: Dict[str, object] | None) -> Dict[str, object]:
        definition = tool_map.get(name)
        if definition is None:
            raise ValueError(f"tool '{name}' is not registered")
        try:
            payload = definition.call(ops, arguments or {})
        except HwpxOperationError as exc:
            raise RuntimeError(str(exc)) from exc
        except Exception as exc:  # pragma: no cover - defensive
            LOGGER.exception("tool '%s' failed", name)
            raise RuntimeError(str(exc)) from exc
        return payload

    init_options = server.create_initialization_options(NotificationOptions())
    async with stdio_server() as (read_stream, write_stream):
        await server.run(read_stream, write_stream, init_options)


def main() -> int:
    configure_logging(os.getenv("LOG_LEVEL"))

    base_directory = Path.cwd()
    LOGGER.info(
        "Using current working directory for file operations",
        extra={"root": str(base_directory)},
    )

    paging_limit = os.getenv("HWPX_MCP_PAGING_PARA_LIMIT")
    try:
        paging_value = int(paging_limit) if paging_limit else 2000
    except ValueError:
        LOGGER.warning("Invalid HWPX_MCP_PAGING_PARA_LIMIT, falling back to 2000")
        paging_value = 2000

    ops = HwpxOps(
        base_directory=base_directory,
        paging_paragraph_limit=paging_value,
        auto_backup=_bool_env("HWPX_MCP_AUTOBACKUP"),
        enable_opc_write=_bool_env("HWPX_MCP_ENABLE_OPC_WRITE"),
    )

    tools = build_tool_definitions()

    try:
        anyio.run(_serve, ops, tools)
    except KeyboardInterrupt:  # pragma: no cover - graceful shutdown
        LOGGER.info("Received interrupt, shutting down")
        return 130

    return 0


if __name__ == "__main__":  # pragma: no cover
    raise SystemExit(main())