"""
asgi-runway — requests-in-queue metrics for Uvicorn/FastAPI autoscaling.


Quick start::

    from fastapi import FastAPI
    from asgi_runway import RunwayMiddleware, metrics_router

    app = FastAPI()
    app.add_middleware(RunwayMiddleware)
    app.include_router(metrics_router)

Then scrape ``/metrics`` and use ``runway_requests_in_flight`` as your
Kubernetes HPA / KEDA autoscaling trigger.
"""

from typing import Optional

from asgi_runway._metrics import (
    REQUEST_DURATION_SECONDS,
    REQUESTS_IN_FLIGHT,
    REQUESTS_IN_FLIGHT_BY_ROUTE,
    REQUESTS_TOTAL,
    disable_runtime_metrics,
)
from asgi_runway._middleware import RunwayMiddleware
from asgi_runway._router import metrics_router
from asgi_runway.exporter import start_metrics_server

__all__ = [
    "RunwayMiddleware",
    "metrics_router",
    "setup",
    "start_metrics_server",
    "disable_runtime_metrics",
    # Individual metrics (for custom dashboards / alerting)
    "REQUESTS_IN_FLIGHT",
    "REQUESTS_IN_FLIGHT_BY_ROUTE",
    "REQUESTS_TOTAL",
    "REQUEST_DURATION_SECONDS",
]

__version__ = "0.3.0"


def setup(
    app,
    *,
    metrics_path: str = "/metrics",
    metrics_port: Optional[int] = None,
    include_metrics_route: bool = True,
    include_runtime_metrics: bool = False,
    **middleware_kwargs,
) -> None:
    """
    Convenience helper: attach middleware + metrics endpoint(s) in one call.

    Parameters
    ----------
    app:
        Your FastAPI application.
    metrics_path:
        URL path for the in-app Prometheus scrape endpoint (default
        ``/metrics``). Only used when ``include_metrics_route=True``.
    metrics_port:
        When set, starts an independent metrics HTTP server on this port in a
        background daemon thread. The thread is isolated from the uvicorn
        event loop, so it remains responsive even when the app is under heavy
        load. Recommended for production. Prometheus convention is ``9091``.
    include_metrics_route:
        Whether to mount the ``/metrics`` route on the FastAPI app itself
        (default ``True``). Set to ``False`` when using ``metrics_port`` so
        scrapes go to the dedicated server only.
    include_runtime_metrics:
        Whether to keep the default Python runtime metrics that
        ``prometheus_client`` registers automatically: ``python_gc_*``,
        ``python_info``, and ``process_*``. Defaults to ``False`` — only
        runway metrics appear in the scrape output. Set to ``True`` if you
        want process-level observability (memory, CPU, GC pressure).
    **middleware_kwargs:
        Forwarded to :class:`RunwayMiddleware` (e.g. ``exclude_paths``,
        ``route_groups``).

    Examples::

        # Simplest — in-app /metrics (current behaviour)
        setup(app)

        # Dedicated metrics server on port 9091, no in-app route
        setup(app, metrics_port=9091, include_metrics_route=False)

        # Both: dedicated server AND in-app route (e.g. during migration)
        setup(app, metrics_port=9091)

        # Per-route granularity
        setup(app, route_groups=[(r"^/infer", "inference")])
    """
    if not include_runtime_metrics:
        disable_runtime_metrics()

    app.add_middleware(RunwayMiddleware, **middleware_kwargs)

    if metrics_port is not None:
        start_metrics_server(port=metrics_port)

    if include_metrics_route and metrics_router is not None:
        if metrics_path != "/metrics":
            from fastapi import APIRouter
            from fastapi.responses import Response
            from prometheus_client import CONTENT_TYPE_LATEST, generate_latest

            from asgi_runway._metrics import _make_registry

            custom_router = APIRouter()

            @custom_router.get(metrics_path, include_in_schema=False)
            def _custom_metrics() -> Response:
                return Response(
                    content=generate_latest(_make_registry()),
                    media_type=CONTENT_TYPE_LATEST,
                )

            app.include_router(custom_router)
        else:
            app.include_router(metrics_router)
