"""API gateway skeleton for multi-tenant request processing.

The gateway does not replace existing Flask routes yet. Instead, it provides a
composable flow that the main entry point can adopt gradually while leaving all
existing applications under ``/apps`` untouched.
"""

from __future__ import annotations

import uuid
from typing import Any

from flask import Request

from platform.gateway.request_context import RequestContext
from platform.gateway.signature_validator import SignatureValidator
from platform.logging.platform_logger import get_platform_logger
from platform.quotas.quota_guard import QuotaGuard
from platform.quotas.rate_limiter import RateLimiter
from platform.routing.app_router import AppRouter
from platform.routing.db_router import DatabaseRouter
from platform.routing.storage_router import StorageRouter
from platform.tenants.tenant_resolver import TenantResolver


class APIGateway:
    """Coordinate tenant resolution, guards, and app dispatch."""

    def __init__(
        self,
        *,
        tenant_resolver: TenantResolver | None = None,
        db_router: DatabaseRouter | None = None,
        storage_router: StorageRouter | None = None,
        app_router: AppRouter | None = None,
        rate_limiter: RateLimiter | None = None,
        quota_guard: QuotaGuard | None = None,
        signature_validator: SignatureValidator | None = None,
    ) -> None:
        self.tenant_resolver = tenant_resolver or TenantResolver()
        self.db_router = db_router or DatabaseRouter()
        self.storage_router = storage_router or StorageRouter()
        self.app_router = app_router or AppRouter()
        self.rate_limiter = rate_limiter or RateLimiter()
        self.quota_guard = quota_guard or QuotaGuard()
        self.signature_validator = signature_validator or SignatureValidator()
        self.logger = get_platform_logger("api_gateway")

    def build_request_context(self, request: Request, *, auth: dict[str, Any] | None = None) -> RequestContext:
        """Resolve the request into a normalized platform context."""
        tenant = self.tenant_resolver.resolve_from_request(request)
        app_id = self.app_router.resolve_app_id(request.path)
        db_binding = self.db_router.resolve(tenant=tenant, app_id=app_id)
        storage_binding = self.storage_router.resolve(tenant=tenant, app_id=app_id)
        limits = self.quota_guard.describe_limits(tenant=tenant, app_id=app_id)
        return RequestContext(
            request_id=str(uuid.uuid4()),
            tenant=tenant,
            app=app_id,
            db=db_binding,
            storage=storage_binding,
            limits=limits,
            auth=auth or {},
        )

    def preflight(self, request: Request, *, auth: dict[str, Any] | None = None) -> RequestContext:
        """Run lightweight gateway checks and return the request context."""
        context = self.build_request_context(request, auth=auth)
        self.rate_limiter.check(request=request, tenant=context.tenant, app_id=context.app)
        self.quota_guard.check(tenant=context.tenant, app_id=context.app)
        self.logger.info("gateway.preflight", extra={"context": context.as_dict()})
        return context

