import logging
import time
from uuid import uuid4

from fastapi import Request

logger = logging.getLogger("gisweb.multitenant.config")

class RequestContextFilter(logging.Filter):
    def __init__(self, config):
        super().__init__()
        self.config = config

    def filter(self, record: logging.LogRecord) -> bool:
        record.tenant = self.config.current_tenant() or "-"
        record.user_id = self.config.current_user_id() or "-"
        record.request_id = self.config.current_request_id() or "-"
        return True
    
def configure_logging(config, level: int = logging.INFO):
    handler = logging.StreamHandler()
    handler.setFormatter(
        logging.Formatter(
            "%(asctime)s %(levelname)s "
            "[tenant=%(tenant)s user_id=%(user_id)s request_id=%(request_id)s] "
            "%(name)s: %(message)s"
        )
    )
    handler.addFilter(RequestContextFilter(config))

    root_logger = logging.getLogger()
    root_logger.setLevel(level)
    root_logger.handlers.clear()
    root_logger.addHandler(handler)
    
async def logging_context_middleware(request: Request, call_next):
    config = request.app.state.multitenant_config

    request_id = request.headers.get("X-Request-Id") or str(uuid4())

    try:
        tenant = config.get_tenant(request)
    except Exception:
        tenant = None

    try:
        user_id = config.get_user_id(request)
    except Exception:
        user_id = None

    start = time.perf_counter()

    with (
        config.request_id_context(request_id),
        config.tenant_context(tenant),
        config.user_id_context(user_id),
    ):
        response = await call_next(request)

        duration = round((time.perf_counter() - start) * 1000, 2)

        logging.getLogger("http").info(
            "%s %s -> %s (%sms)",
            request.method,
            request.url.path,
            response.status_code,
            duration,
        )

        response.headers["X-Request-Id"] = request_id
        return response