import time
import uuid
from contextvars import ContextVar
from typing import Final, Optional, Awaitable

import aiohttp
from aiohttp import web
import secrets
import warnings


X_REQUEST_ID: Final[str] = 'X-Request-ID'
CONTEXT_VAR_REQUEST_ID: ContextVar[Optional[str]] = ContextVar(X_REQUEST_ID, default=None)


def generate_random_request_id() -> str:
    warnings.warn('generate_random_request_id is deprecated, replace it with generate_request_id', DeprecationWarning)
    return str(uuid.uuid4())


def generate_request_id(client_addr: str | None) -> str:
    return f'{secrets.token_hex(16)}-{client_addr}-{time.time()}'


@web.middleware
async def request_tracing_middleware(
        request: web.Request, handler: aiohttp.typedefs.Handler, *args, **kwargs
) -> web.StreamResponse | Awaitable[web.StreamResponse]:
    request_id = request.headers.get(X_REQUEST_ID, generate_request_id(request.remote))
    CONTEXT_VAR_REQUEST_ID.set(request_id)
    response = await handler(request)
    response.headers[X_REQUEST_ID] = request_id
    return response
