"""FastAPI middleware for API key authentication."""

from __future__ import annotations

from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from starlette.responses import JSONResponse

from cube_cloud.auth import api_keys, profiles


class APIKeyMiddleware(BaseHTTPMiddleware):
    """Validate API key from Authorization header on every request.

    Populates request.state with:
      - profile: str (the profile name)
      - apollo_client_id: str
      - apollo_client_secret: str
    """

    # Paths that skip auth (health checks, browser login, setup guide)
    EXEMPT_PATHS = {"/health", "/healthz", "/ready", "/auth/login", "/auth/authenticate", "/setup"}
    EXEMPT_PREFIXES = ("/auth/session/", "/static/",)

    async def dispatch(self, request: Request, call_next):
        path = request.url.path
        if path in self.EXEMPT_PATHS or path.startswith(self.EXEMPT_PREFIXES):
            return await call_next(request)

        auth_header = request.headers.get("authorization", "")
        if not auth_header.startswith("Bearer "):
            return JSONResponse(
                status_code=401,
                content={"error": "Missing or invalid Authorization header. Expected: Bearer <api-key>"},
            )

        raw_key = auth_header[7:]  # strip "Bearer "

        item = await api_keys.validate_key(raw_key)
        if not item:
            return JSONResponse(
                status_code=401,
                content={"error": "Invalid or revoked API key"},
            )

        profile_name = item["profile"]

        try:
            client_id, client_secret = profiles.get_credentials(profile_name)
        except ValueError as e:
            return JSONResponse(
                status_code=403,
                content={"error": str(e)},
            )

        request.state.profile = profile_name
        request.state.apollo_client_id = client_id
        request.state.apollo_client_secret = client_secret

        return await call_next(request)
