"""DRF authentication class backed by :class:`mcp_server.models.UserToken`.

Wraps :func:`mcp_server.auth.resolve_mcp_user` so a single verification
routine serves both surfaces:

* the FastMCP middleware on ``/mcp/`` (via ``MCPAuthMiddleware``); and
* the Django REST surface on ``/library/api/*`` and
  ``/mcp_server/api/teams/*`` (via this class).

Scope: this class authenticates the caller — it does *not* honour the
token's ``allowed_libraries`` / ``allowed_tools`` fields. Those apply
only to the MCP tool surface. On the REST endpoints, access is gated by
``Team.owner`` and ``Library.owner_username`` rather than per-token
scope claims; treating ``allowed_libraries`` as authoritative there
would either force Daedalus to mint an effectively-unrestricted token
(redundant with the user identity) or invent a per-endpoint scope
mapping with no natural shape.

The accepted header is ``Authorization: Bearer <plaintext>``.
"""

from __future__ import annotations

from rest_framework import authentication, exceptions

from .auth import MCPAuthError, resolve_mcp_user


def request_token_label(request):
    """Name of the ``UserToken`` authenticating this request, or None.

    Session-authenticated requests (``request.auth`` is None) and blank
    token names return None — the caller treats both as "no managing app".
    """
    from .models import UserToken

    token = getattr(request, "auth", None)
    if isinstance(token, UserToken):
        return token.name.strip() or None
    return None


class UserTokenAuthentication(authentication.BaseAuthentication):
    """Authenticate DRF requests with a ``UserToken`` bearer."""

    keyword = "Bearer"

    def authenticate(self, request):
        header = authentication.get_authorization_header(request).decode("iso-8859-1")
        if not header:
            return None
        parts = header.split()
        if len(parts) < 2 or parts[0] != self.keyword:
            # Not our scheme. Let other authenticators try.
            return None
        if len(parts) > 2:
            raise exceptions.AuthenticationFailed(
                "Invalid Authorization header: too many components."
            )

        try:
            user, token = resolve_mcp_user(parts[1])
        except MCPAuthError as exc:
            raise exceptions.AuthenticationFailed(str(exc))
        return user, token

    def authenticate_header(self, request):
        return self.keyword
