"""Middleware propio de la aplicacion."""

from __future__ import annotations

import re
import uuid

from core.logging_utils import request_id_var

# El identificador que manda el cliente se acepta solo si tiene una forma
# inocua. Sin esta validacion, un valor con saltos de linea podria inyectar
# cabeceras en la respuesta o falsear lineas en los registros.
_SAFE_REQUEST_ID = re.compile(r"^[A-Za-z0-9._\-]{8,64}$")

REQUEST_ID_HEADER = "HTTP_X_REQUEST_ID"
RESPONSE_HEADER = "X-Request-ID"


class RequestIDMiddleware:
    """
    Asigna un identificador de correlacion a cada peticion.

    Se reutiliza el que venga en `X-Request-ID` si es valido; si no, se genera
    uno. Queda disponible en `request.request_id`, en todos los registros de
    esa peticion y en la cabecera de respuesta.
    """

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        incoming = request.META.get(REQUEST_ID_HEADER, "")
        request_id = incoming if _SAFE_REQUEST_ID.match(incoming) else uuid.uuid4().hex

        request.request_id = request_id
        token = request_id_var.set(request_id)
        try:
            response = self.get_response(request)
        finally:
            request_id_var.reset(token)

        response[RESPONSE_HEADER] = request_id
        return response
