"""Per-turn, request-scoped state shared between the bridge, the reply engine
and tools — without threading extra parameters through the whole engine call
chain (run_reply_engine -> run_tool_with_retries -> execute_tool -> execute).

Flask serves each HTTP request on its own thread and the reply engine + tools
run synchronously on that thread, so a ``threading.local`` cleanly scopes a
single turn. Anything that can't see the thread-local (a worker thread, an eval,
a unit test) just reads ``None`` and the caller falls back to its default.

Fields
------
broadcasting : Optional[bool]
    The live screen-share (Go-Live) state the bot sends with the request. The
    webSearch routing reads it to pick on-screen Chrome (live) vs Gemini (off).
broadcast_action : Optional[str]
    A directive ("start"/"stop") recorded by the setBroadcast tool for the
    bridge to return to the bot, which owns the actual broadcast.
"""

from __future__ import annotations

import threading
from typing import Optional

_state = threading.local()


def reset() -> None:
    """Clear per-turn state. Call at the start of each request."""
    _state.broadcasting = None
    _state.broadcast_action = None


def set_broadcasting(value: Optional[bool]) -> None:
    _state.broadcasting = value


def get_broadcasting() -> Optional[bool]:
    return getattr(_state, "broadcasting", None)


def request_broadcast(action: str) -> None:
    """Record a broadcast directive. ``action`` is "start" or "stop"."""
    _state.broadcast_action = action


def get_broadcast_action() -> Optional[str]:
    return getattr(_state, "broadcast_action", None)
