from typing import TYPE_CHECKING

from ntrp.logging import get_logger
from ntrp.tools.core.base import ToolResult
from ntrp.tools.core.context import ToolExecution
from ntrp.tools.core.registry import ToolRegistry
from ntrp.tools.discover import discover_user_tools
from ntrp.tools.specs import ALL_TOOLS

if TYPE_CHECKING:
    from ntrp.server.runtime import Runtime

_logger = get_logger(__name__)


class ToolExecutor:
    def __init__(self, runtime: "Runtime"):
        self.runtime = runtime
        self.registry = ToolRegistry()
        for cls in ALL_TOOLS:
            self.registry.register(cls())
        for cls in discover_user_tools():
            if cls.name in self.registry:
                _logger.warning("User tool %r skipped — conflicts with built-in", cls.name)
            else:
                self.registry.register(cls())
                _logger.info("Loaded user tool: %s", cls.name)

    def with_registry(self, registry: ToolRegistry) -> "ToolExecutor":
        clone = ToolExecutor.__new__(ToolExecutor)
        clone.runtime = self.runtime
        clone.registry = registry
        return clone

    async def execute(self, tool_name: str, arguments: dict, execution: ToolExecution) -> ToolResult:
        tool = self.registry.get(tool_name)
        if not tool:
            return ToolResult(
                content=f"Unknown tool: {tool_name}. Check available tools in the system prompt.",
                preview="Unknown tool",
            )

        return await self.registry.execute(tool_name, execution, arguments)

    def get_tools(self, mutates: bool | None = None) -> list[dict]:
        return self.registry.get_schemas(
            capabilities=frozenset(self.runtime.tool_services),
            mutates=mutates,
        )

    def get_tool_metadata(self) -> list[dict]:
        return [tool.get_metadata() for tool in self.registry.tools.values()]
