"""Middleware for API key authentication."""

from collections.abc import Awaitable
from collections.abc import Callable
from typing import ClassVar

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

from fenliu.services.api_key import validate_api_key


class APIKeyMiddleware(BaseHTTPMiddleware):
    """Middleware to validate API key for protected API endpoints.

    Protects all /api/v1/* routes except those in the exempt list.
    The API key should be provided in the X-API-Key header.
    """

    # These endpoints don't require API key authentication
    AUTH_EXEMPT_PATHS: ClassVar[list[str]] = [
        "/api/v1/api-keys/status",
        "/api/v1/api-keys/generate",
        "/api/v1/api-keys/revoke",
    ]

    async def dispatch(self, request: Request, call_next: Callable[[Request], Awaitable[Response]]) -> Response:
        """Process request and validate API key if needed."""
        # Only validate /api/v1/* paths
        if request.url.path.startswith("/api/v1"):
            # Skip auth for exempt paths
            if any(request.url.path.startswith(path) for path in self.AUTH_EXEMPT_PATHS):
                return await call_next(request)

            # Validate API key for all other /api/v1/* paths
            api_key = request.headers.get("X-API-Key")

            if not validate_api_key(api_key):
                return JSONResponse(
                    {
                        "success": False,
                        "error": "Unauthorized: Invalid or missing API key",
                    },
                    status_code=401,
                )

        return await call_next(request)
