"""
CASE Transport Layer

HTTP transport for CASE API communication.
CASE uses the IMS Global error format, handled by the base transport's
built-in IMS error parsing. CASE list endpoints use header-based pagination
(same as OneRoster).
"""

from __future__ import annotations

import re
from typing import TYPE_CHECKING, Any

from timeback_common import BaseTransport, CasePaths, TokenManager
from timeback_common.pagination import PageResult

if TYPE_CHECKING:
    import httpx

_NEXT_LINK_RE = re.compile(r"""rel=["']?next["']?(?:\s|;|,|$)""", re.IGNORECASE)


def _has_next_link(link_header: str | None) -> bool:
    """Check if a Link header contains a ``rel="next"`` relation."""
    if not link_header:
        return False
    return _NEXT_LINK_RE.search(link_header) is not None


def parse_header_pagination(response: httpx.Response, data: list[Any]) -> PageResult[Any]:
    """Parse pagination metadata from HTTP response headers.

    Reads ``X-Total-Count`` for total item count and ``Link`` for
    ``rel="next"`` to determine whether more pages exist.  This mirrors
    the TypeScript SDK's ``parseHeaderPagination()`` utility.
    """
    link_header = response.headers.get("Link")
    total_header = response.headers.get("X-Total-Count")

    total: int | None = None
    if total_header is not None:
        try:
            total = int(total_header)
        except (ValueError, TypeError):
            total = None

    return PageResult(
        data=data,
        has_more=_has_next_link(link_header),
        total=total,
    )


class Transport(BaseTransport):
    """HTTP transport layer for CASE API communication."""

    def __init__(
        self,
        *,
        base_url: str,
        token_manager: TokenManager | None = None,
        paths: CasePaths,
        timeout: float = 30.0,
        http_client: httpx.AsyncClient | None = None,
        no_auth: bool = False,
    ) -> None:
        super().__init__(
            base_url=base_url,
            timeout=timeout,
            token_manager=token_manager,
            http_client=http_client,
            no_auth=no_auth,
        )
        self.paths = paths

    async def request_paginated(
        self,
        path: str,
        *,
        params: dict[str, Any] | None = None,
    ) -> PageResult[Any]:
        """Make a paginated GET request using header-based pagination.

        Returns the parsed JSON body wrapped in a ``PageResult`` that
        includes ``has_more`` (derived from the ``Link`` header) and an
        optional ``total`` (from ``X-Total-Count``).

        This mirrors the TypeScript CASE transport's
        ``requestPaginated<T>()`` method.
        """
        response = await self.request_raw("GET", path, params=params)
        data = response.json()
        if not isinstance(data, list):
            data = [data]
        return parse_header_pagination(response, data)


__all__ = ["Transport", "parse_header_pagination"]
