"""Access token authentication middleware.

Validates requests against a configured access token passed via query param,
header, or cookie.
"""

from starlette.middleware.base import BaseHTTPMiddleware, RequestResponseEndpoint
from starlette.requests import Request
from starlette.responses import JSONResponse, Response
from starlette.types import ASGIApp

from mm_base6.server.utils import redirect

# Name of the query param, header, and cookie used for access token auth
ACCESS_TOKEN_NAME = "access-token"  # noqa: S105  # nosec B105


class AccessTokenMiddleware(BaseHTTPMiddleware):
    """Middleware that validates access tokens from query params, headers, or cookies."""

    def __init__(self, app: ASGIApp, access_token: str) -> None:
        """Initialize middleware with the required access token."""
        super().__init__(app)
        self.access_token = access_token

    async def dispatch(self, request: Request, call_next: RequestResponseEndpoint) -> Response:
        """Check access token and redirect to login or return 401 if invalid."""
        if request.url.path.startswith("/auth/"):
            return await call_next(request)

        success = (
            request.query_params.get(ACCESS_TOKEN_NAME) == self.access_token
            or request.headers.get(ACCESS_TOKEN_NAME) == self.access_token
            or request.cookies.get(ACCESS_TOKEN_NAME) == self.access_token
        )
        if success:
            return await call_next(request)

        if request.url.path.startswith("/api/"):
            return JSONResponse({"error": "access denied"}, status_code=401)
        return redirect("/auth/login")
