"""API authentication for Robot Resources proxy.

Implements Bearer token authentication with:
- Timing-safe comparison via ``secrets.compare_digest``
- Dev mode bypass when ``ROUTER_API_KEY`` is unset
- RFC 6750 error responses (``WWW-Authenticate: Bearer`` header)
"""

from __future__ import annotations

import secrets

from fastapi import HTTPException, Request, Security, status
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer

from robot_resources.config import get_settings

# auto_error=False: don't auto-raise 403 when no Authorization header.
# We handle missing credentials ourselves to provide proper 401 response.
_bearer_scheme = HTTPBearer(auto_error=False)


def verify_api_key(
    credentials: HTTPAuthorizationCredentials | None = Security(_bearer_scheme),
) -> None:
    """FastAPI dependency that enforces Bearer token authentication.

    Behavior:
        - ``ROUTER_API_KEY`` not set / empty: all requests allowed (dev mode).
        - ``ROUTER_API_KEY`` set: requires ``Authorization: Bearer <token>``.

    Raises:
        HTTPException: 401 with ``WWW-Authenticate: Bearer`` header
            if authentication fails.
    """
    settings = get_settings()

    if not settings.router_api_key:
        return  # Dev mode — no auth required

    if credentials is None:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Missing authentication token",
            headers={"WWW-Authenticate": "Bearer"},
        )

    # Timing-safe comparison prevents side-channel attacks
    if not secrets.compare_digest(
        credentials.credentials.encode("utf-8"),
        settings.router_api_key.encode("utf-8"),
    ):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Invalid authentication token",
            headers={"WWW-Authenticate": "Bearer"},
        )


def verify_api_key_or_localhost(
    request: Request,
    credentials: HTTPAuthorizationCredentials | None = Security(_bearer_scheme),
) -> None:
    """Like ``verify_api_key`` but allows unauthenticated localhost access.

    Used for recommendation-only endpoints (e.g. ``/v1/route``) that make
    no upstream API calls and pose no cost or data risk.
    """
    if request.client and request.client.host in ("127.0.0.1", "::1"):
        return  # Localhost — no auth required
    verify_api_key(credentials)
