"""REST adapter — exposes all MCP tools at /v1/{module}/{tool_name}.

Maps URL path segments to tool domains using PREFIX_DOMAIN_MAP from
DynamicToolRegistry, then delegates execution to ToolRegistry.
"""

from __future__ import annotations

import logging
from typing import Any, Dict

from fastapi import APIRouter, Depends, Request
from fastapi.responses import JSONResponse

from ..context import RequestContext
from ..registry import ToolRegistry

logger = logging.getLogger(__name__)

router = APIRouter(prefix="/v1", tags=["REST API"])

# Module-level reference set by app.py at startup
_registry: ToolRegistry | None = None
_tenant_registry: Any = None


def init_rest(registry: ToolRegistry, tenant_registry: Any = None) -> None:
    """Wire the shared ToolRegistry into this adapter."""
    global _registry, _tenant_registry
    _registry = registry
    _tenant_registry = tenant_registry


async def _get_context(request: Request) -> RequestContext:
    """Dependency: build RequestContext from the HTTP request."""
    from ..middleware.auth import get_request_context
    return await get_request_context(request, _tenant_registry, protocol="rest")


def _resolve_tool_id(module: str, tool_name: str) -> str:
    """Map REST path segments to a tool ID.

    Strategy:
    1. Direct match: module_tool_name (e.g. "hierarchy" + "tree" → "hierarchy_tree")
    2. Exact tool_name if it exists in the registry
    3. Fallback: tool_name as-is (for tools without a prefix)
    """
    # Try {module}_{tool_name} first
    candidate = f"{module}_{tool_name}"
    if _registry and candidate in _registry.get_all_tools():
        return candidate

    # Try tool_name directly
    if _registry and tool_name in _registry.get_all_tools():
        return tool_name

    # Fallback to the combined form
    return candidate


# ------------------------------------------------------------------
# Routes
# ------------------------------------------------------------------

@router.post("/{module}/{tool_name}")
async def invoke_tool(
    module: str,
    tool_name: str,
    request: Request,
    context: RequestContext = Depends(_get_context),
) -> JSONResponse:
    """Invoke an MCP tool via REST.

    Path: POST /v1/{module}/{tool_name}
    Body: JSON dict of tool arguments.
    """
    try:
        body: Dict[str, Any] = await request.json()
    except Exception:
        body = {}

    tool_id = _resolve_tool_id(module, tool_name)
    result = await _registry.invoke(tool_id, body, context)

    status = result.get("code", 200)
    if "code" in result:
        result = {k: v for k, v in result.items() if k != "code"}

    return JSONResponse(content=result, status_code=status)


@router.get("/tools")
async def list_tools(
    domain: str = "",
    query: str = "",
    context: RequestContext = Depends(_get_context),
) -> JSONResponse:
    """Discover tools — list by domain, search by query, or get all domains."""
    if query:
        return JSONResponse(content=_registry.search_tools(query))
    if domain:
        return JSONResponse(content=_registry.get_tools_by_domain(domain))
    return JSONResponse(content=_registry.get_all_domains())


@router.get("/domains")
async def list_domains(context: RequestContext = Depends(_get_context)) -> JSONResponse:
    """List all tool domains with descriptions and tool counts."""
    return JSONResponse(content=_registry.get_all_domains())
