"""Uvicorn server entrypoint with structlog integration.

This module configures structlog first, then starts Uvicorn with a
logging configuration that propagates Uvicorn logs to the root logger,
so they are rendered by structlog in JSON when running in containers.
"""

from __future__ import annotations

import os
from typing import Any

import uvicorn

from .api import app  # FastAPI app
from .common.utils import configure_logging


def build_incremental_log_config(level: str) -> dict[str, Any]:
    """Return a minimal incremental logging config for Uvicorn.

    This avoids overriding the root logger/handlers installed by
    ``configure_logging`` and simply ensures Uvicorn loggers propagate
    upwards to be formatted by structlog.
    """
    lvl = level.upper()
    return {
        "version": 1,
        "incremental": True,  # don't touch existing root handlers
        # Uvicorn mutates formatter.default.use_colors unconditionally; provide a stub.
        "formatters": {
            "default": {
                "()": "uvicorn.logging.DefaultFormatter",
                "fmt": "%(levelprefix)s %(message)s",
                "use_colors": False,
            },
            "access": {
                "()": "uvicorn.logging.AccessFormatter",
                "fmt": (
                    "%(levelprefix)s %(client_addr)s - "
                    '"%(request_line)s" '
                    "%(status_code)s"
                ),
                "use_colors": False,
            },
        },
        "loggers": {
            "uvicorn": {"level": lvl, "propagate": True},
            "uvicorn.error": {"level": lvl, "propagate": True},
            "uvicorn.access": {"level": lvl, "propagate": True},
            "uvicorn.asgi": {"level": lvl, "propagate": True},
        },
        "disable_existing_loggers": False,
    }


def main() -> None:
    # Configure structlog + stdlib once
    configure_logging()

    host = os.getenv("HOST", "0.0.0.0")
    port = int(os.getenv("PORT", "8000"))
    log_level = os.getenv("LOG_LEVEL", "INFO").lower()

    log_config = build_incremental_log_config(log_level)

    # Start Uvicorn programmatically so our logging stays intact
    uvicorn.run(
        app,
        host=host,
        port=port,
        log_config=log_config,
        # Keep access log enabled; it will propagate to structlog
        access_log=True,
        # Disable color codes in non-TTY environments
        use_colors=False,
    )


if __name__ == "__main__":
    main()
