"""HTTP tracing utilities shared by SDK middleware."""

from __future__ import annotations

import json
import secrets
from dataclasses import dataclass, field
from typing import Optional


def _new_hex_id(n_bytes: int = 16) -> str:
    return secrets.token_hex(n_bytes)


@dataclass
class HttpSpan:
    """Represents a single HTTP request span."""

    trace_id: str
    span_id: str
    _fn: str = field(repr=False)
    _started_at: int = field(repr=False)
    _client: object = field(repr=False)  # ServiceBridge, avoid circular import
    _input_buf: bytes = field(repr=False)

    def end(self, status_code: int = 0, error: str = "", success: Optional[bool] = None) -> None:
        """Close the span and report telemetry."""
        if success is None:
            success = 0 < status_code < 400
        output_buf = json.dumps({"statusCode": status_code, "error": error}).encode()
        self._client._report_call(
            self.trace_id,
            self.span_id,
            self._fn,
            self._started_at,
            self._input_buf,
            success,
            1,
            output_buf,
            error,
            span_type="http",
        )


def extract_trace_from_headers(headers: dict[str, str]) -> tuple[str, str]:
    """Extract trace context from HTTP headers.

    Returns (trace_id, parent_span_id).
    Priority: W3C traceparent > x-trace-id > generate new.
    """
    lower = {k.lower(): v for k, v in headers.items()}

    if tp := lower.get("traceparent", ""):
        parts = tp.strip().split("-")
        if len(parts) == 4 and parts[0] == "00" and len(parts[1]) == 32 and len(parts[2]) == 16:
            return parts[1], parts[2]

    if x_trace := lower.get("x-trace-id", ""):
        return x_trace.strip(), ""

    return _new_hex_id(16), ""
