"""Namespace management — CRUD operations for namespaces."""

from __future__ import annotations

import httpx

from primitif._transport import configure_logging, request_with_retries
from primitif.namespace.exceptions import (
    NamespaceAuthError,
    NamespaceError,
    NamespaceLimitError,
    NamespaceNetworkError,
    NamespaceNotFoundError,
    NamespaceRateLimitError,
    NamespaceServerError,
    NamespaceValidationError,
)
from primitif.namespace.models import Namespace, NamespaceWithToken

logger = configure_logging("namespace")

_EXC_MAP = {
    401: NamespaceAuthError,
    403: NamespaceLimitError,
    404: NamespaceNotFoundError,
    422: NamespaceValidationError,
    429: NamespaceRateLimitError,
}


class NamespaceAdmin:
    """Namespace operations — create, list, get, delete, rotate.

    Not instantiated directly. Access via ``Primitif().namespaces``.
    """

    def __init__(self, client: httpx.Client, max_retries: int) -> None:
        self._client = client
        self._max_retries = max_retries

    def _request(self, method: str, path: str, **kwargs) -> dict:
        return request_with_retries(
            self._client,
            method,
            path,
            self._max_retries,
            exc_map=_EXC_MAP,
            server_exc=NamespaceServerError,
            base_exc=NamespaceError,
            connection_exc=NamespaceNetworkError,
            logger=logger,
            **kwargs,
        )

    def create(self, name: str) -> NamespaceWithToken:
        """Create a namespace. Returns the namespace with a one-time token."""
        data = self._request("POST", "/api/v1/namespaces", json={"name": name})
        return NamespaceWithToken(**data)

    def list(self) -> list[Namespace]:
        """List all namespaces for the organisation."""
        data = self._request("GET", "/api/v1/namespaces")
        return [Namespace(**ns) for ns in data["items"]]

    def get(self, namespace_id: str) -> Namespace:
        """Get a namespace by ID."""
        data = self._request("GET", f"/api/v1/namespaces/{namespace_id}")
        return Namespace(**data)

    def delete(self, namespace_id: str) -> None:
        """Delete a namespace. Cannot delete the default namespace."""
        self._request("DELETE", f"/api/v1/namespaces/{namespace_id}")

    def rotate_token(self, namespace_id: str) -> NamespaceWithToken:
        """Rotate the token for a namespace. Returns the new token."""
        data = self._request("POST", f"/api/v1/namespaces/{namespace_id}/rotate")
        return NamespaceWithToken(**data)
