"""HTTP client for registering tools with Pillar Cloud.

Uses only ``urllib.request`` from the standard library so the SDK has zero
runtime dependencies.
"""
from __future__ import annotations

import json
import logging
import urllib.error
import urllib.request
from typing import TYPE_CHECKING, Any

from pillar._errors import RegistrationError

if TYPE_CHECKING:
    from pillar._decorator import ToolRegistration

logger = logging.getLogger("pillar")

_SDK_VERSION = "pillar-python/0.1.0"


def _tool_payload(reg: ToolRegistration) -> dict[str, Any]:
    """Serialize a ``ToolRegistration`` into the registration API format."""
    payload: dict[str, Any] = {
        "name": reg.name,
        "description": reg.description,
        "inputSchema": reg.input_schema,
        "timeout_ms": reg.timeout_ms,
        "channel_compatibility": reg.channel_compatibility,
        "tool_type": reg.tool_type,
    }
    if reg.guidance:
        payload["guidance"] = reg.guidance
    if reg.output_schema:
        payload["outputSchema"] = reg.output_schema
    return payload


def register_tools(
    *,
    secret: str,
    base_url: str,
    endpoint_url: str,
    tools: dict[str, ToolRegistration],
) -> dict[str, Any]:
    """POST tool schemas to ``/api/tools/register/``.

    Raises :class:`RegistrationError` on HTTP or network failure.
    """
    url = f"{base_url.rstrip('/')}/api/tools/register/"
    body = json.dumps({
        "endpoint_url": endpoint_url,
        "tools": [_tool_payload(t) for t in tools.values()],
        "sdk_version": _SDK_VERSION,
    }).encode()

    req = urllib.request.Request(
        url,
        data=body,
        headers={
            "Authorization": f"Bearer {secret}",
            "Content-Type": "application/json",
        },
        method="POST",
    )

    try:
        with urllib.request.urlopen(req, timeout=15) as resp:
            data = json.loads(resp.read().decode())
            logger.info(
                "Registered %d tool(s) with Pillar Cloud: %s",
                len(tools),
                data.get("registered", []),
            )
            return data
    except urllib.error.HTTPError as exc:
        body_text = exc.read().decode(errors="replace")
        raise RegistrationError(
            f"Registration failed (HTTP {exc.code}): {body_text}"
        ) from exc
    except urllib.error.URLError as exc:
        raise RegistrationError(
            f"Could not reach Pillar Cloud at {url}: {exc.reason}"
        ) from exc
