"""
Async-context (contextvars) support for Visibe request-scoped tracing.

_active_session is set by Visibe.session(), flask_middleware(), and
starlette_middleware() before user/route-handler code runs.

All three Visibe methods that touch the backend check this ContextVar:
  - create_trace()   → no-op when a session is active (session owns the trace)
  - queue_span()     → redirects spans to the session's trace_id
  - complete_trace() → accumulates stats into the session, skips the backend call

ContextVar is both thread-safe (WSGI / Flask — one thread per request) and
asyncio-safe (ASGI / FastAPI — one task per request).  Concurrent requests
are fully isolated without any additional locking.
"""
from contextvars import ContextVar
from dataclasses import dataclass, field
from typing import Optional


@dataclass
class _SessionContext:
    """State for one active session trace.

    Created by session() / middleware before user code runs.
    Accumulators are updated by complete_trace() each time an
    integration finishes an individual LLM call or agent turn.
    """
    trace_id: str
    llm_call_count: int = 0
    total_input: int = 0
    total_output: int = 0
    total_cost: float = 0.0


# The active session for the current async context (coroutine chain / thread).
# None means no session is active — all SDK calls behave normally.
_active_session: ContextVar[Optional[_SessionContext]] = ContextVar(
    '_active_session', default=None
)
