# File: src/noveler/infrastructure/json/mcp/servers/tool_registry.py
# Purpose: Manage tool registration and schema discovery for JSON conversion MCP server
# Context: Extracted from JSONConversionServer to improve single responsibility principle

"""Tool registration and discovery manager for MCP JSON conversion server.

This module provides centralized tool registration, schema management, and tool
discovery for the MCP JSON conversion server. It separates tool registration logic
from the main server orchestration, improving maintainability and testability.

Components:
- ToolRegistry: Central registry for all MCP tools
- Tool schema management
- Tool discovery and retrieval
"""

from __future__ import annotations

import logging
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any


@dataclass
class ToolDefinition:
    """Tool definition with metadata and schema.

    Attributes:
        name: Unique tool identifier
        handler: Callable function that implements the tool
        input_schema: JSON schema defining input parameters
        description: Human-readable description of the tool
    """

    name: str
    handler: Callable
    input_schema: dict[str, Any]
    description: str


class ToolRegistry:
    """Manages MCP tool registration and discovery.

    Purpose:
        Provides centralized registration, schema management, and discovery
        for all tools provided by the JSON conversion MCP server.

    Responsibilities:
        - Tool registration and validation
        - Schema storage and retrieval
        - Tool lookup and execution
        - Tool listing and metadata

    Context:
        Used by JSONConversionServer to manage tool catalog. Extracted from
        monolithic JSONConversionServer class to improve SRP.

    Design Patterns:
        - Registry Pattern: Centralized tool collection
        - Factory Pattern: Tool definition creation
    """

    def __init__(self, logger: logging.Logger):
        """Initialize tool registry.

        Args:
            logger: Logger instance for tool registration events

        Preconditions:
            - logger must be a valid Logger instance

        Side Effects:
            - Initializes internal tool storage
            - Registers all built-in tools via _initialize_tools()
        """
        self._logger = logger
        self._tools: dict[str, ToolDefinition] = {}
        self._initialize_tools()

    def _initialize_tools(self) -> None:
        """Initialize all built-in registered tools.

        Purpose:
            Register all standard tools provided by the MCP server.

        Side Effects:
            - Calls all _register_* methods to populate tool registry
        """
        self._logger.info("Initializing MCP tool registry")
        self._register_tools()
        self._register_write_tools()
        self._register_check_tools()
        self._register_plot_tools()
        self._logger.info(
            "Tool registry initialized with %s tools",
            len(self._tools),
        )

    def register_tool(self, tool: ToolDefinition) -> None:
        """Register a new tool.

        Purpose:
            Add a tool definition to the registry with validation.

        Args:
            tool: ToolDefinition containing tool metadata and handler

        Raises:
            ValueError: If tool name already registered

        Side Effects:
            - Adds tool to internal registry
            - Logs registration event
        """
        if tool.name in self._tools:
            raise ValueError(f"Tool '{tool.name}' already registered")

        self._logger.debug(
            "Registering tool: %s",
            tool.name,
        )
        self._tools[tool.name] = tool

    def get_tool(self, name: str) -> Callable | None:
        """Retrieve a registered tool handler.

        Purpose:
            Get the executable function for a named tool.

        Args:
            name: Tool identifier

        Returns:
            Tool handler callable or None if not found
        """
        tool = self._tools.get(name)
        return tool.handler if tool else None

    def get_tool_definition(self, name: str) -> ToolDefinition | None:
        """Get complete tool definition with schema.

        Purpose:
            Retrieve full tool metadata including schema for MCP protocol.

        Args:
            name: Tool identifier

        Returns:
            ToolDefinition with schema or None if not found
        """
        return self._tools.get(name)

    def list_tools(self) -> list[ToolDefinition]:
        """List all registered tools.

        Purpose:
            Get all tool definitions for MCP protocol advertisement.

        Returns:
            List of all ToolDefinition objects in registry
        """
        return list(self._tools.values())

    def get_tool_schemas(self) -> dict[str, dict[str, Any]]:
        """Get input schemas for all tools.

        Purpose:
            Provide tool schemas in MCP protocol format.

        Returns:
            Dictionary mapping tool names to their input schemas
        """
        return {
            name: tool.input_schema
            for name, tool in self._tools.items()
        }

    def get_all_tool_definitions(self) -> dict[str, ToolDefinition]:
        """Get all tool definitions in the registry.

        Purpose:
            Retrieve all registered tools for batch operations and introspection.

        Returns:
            Dictionary mapping tool names to ToolDefinition objects
        """
        return self._tools.copy()

    def register_all_tools(self, server: Any) -> None:
        """Register all tools with a FastMCP server instance.

        Purpose:
            Convenience method to register all tools with a FastMCP server,
            handling the decoration pattern for tool registration.

        Args:
            server: FastMCP server instance with register_tool capability

        Side Effects:
            - Registers each tool with the server
            - Logs registration summary
        """
        if not hasattr(server, "tool"):
            self._logger.warning("Server instance does not support tool registration")
            return

        registered_count = 0
        for tool_name, tool_def in self._tools.items():
            try:
                # Register tool with server
                server.tool(
                    name=tool_name,
                    description=tool_def.description,
                )(tool_def.handler)
                registered_count += 1
                self._logger.debug(
                    "Registered tool with FastMCP server: %s",
                    tool_name,
                )
            except Exception as e:
                self._logger.error(
                    "Failed to register tool '%s': %s",
                    tool_name,
                    e,
                )

        self._logger.info(
            "Registered %s/%s tools with FastMCP server",
            registered_count,
            len(self._tools),
        )

    # ===== Tool Registration Methods (extracted from JSONConversionServer) =====

    def _register_tools(self) -> None:
        """Register core conversion and CLI tools.

        Purpose:
            Register fundamental tools for file conversion and CLI interaction.
            These tools are registered early in the initialization sequence.
        """
        # Placeholder for tool registration
        # Note: Actual tool implementations are registered by JSONConversionServer
        # This method is called during initialization to establish the registry
        self._logger.debug("Core tools registry initialized (awaiting handler binding)")

    def _register_write_tools(self) -> None:
        """Register writing-related tools.

        Purpose:
            Register tools for manuscript writing, editing, and formatting.
        """
        # Placeholder: These would be implemented based on the original
        # _register_write_tools() method from JSONConversionServer

    def _register_check_tools(self) -> None:
        """Register quality check and validation tools.

        Purpose:
            Register tools for quality assurance, validation, and checking.
        """
        # Placeholder: These would be implemented based on the original
        # _register_check_tools() method from JSONConversionServer

    def _register_plot_tools(self) -> None:
        """Register plot and story management tools.

        Purpose:
            Register tools for plot analysis, design, and management.
        """
        # Placeholder: These would be implemented based on the original
        # _register_plot_tools() method from JSONConversionServer

    def _register_cli_conversion_tool(self) -> None:
        """Register CLI conversion tool."""

    def _register_validation_tool(self) -> None:
        """Register validation tool."""

    def _register_file_reference_tool(self) -> None:
        """Register file reference tool."""

    def _register_novel_tools(self) -> None:
        """Register novel-specific tools."""

    def _register_claude_write_tools(self) -> None:
        """Register Claude-assisted writing tools."""

    def _register_staged_writing_tools(self) -> None:
        """Register staged writing workflow tools."""

    def _register_18step_writing_tools(self) -> None:
        """Register 18-step writing methodology tools."""

    def _register_plot_preparation_tools(self) -> None:
        """Register plot preparation tools."""

    def _register_manuscript_writing_tools(self) -> None:
        """Register manuscript writing tools."""

    def _register_content_analysis_tools(self) -> None:
        """Register content analysis tools."""

    def _register_creative_design_tools(self) -> None:
        """Register creative design tools."""

    def _register_quality_refinement_tools(self) -> None:
        """Register quality refinement tools."""

    def _register_main_check_tools(self) -> None:
        """Register main quality check tools."""

    def _register_specialized_check_tools(self) -> None:
        """Register specialized check tools."""

    def _register_project_tools(self) -> None:
        """Register project management tools."""

    def _register_legacy_compatibility_tools(self) -> None:
        """Register legacy compatibility tools."""
