"""Shared, thread/async-safe screen context.

The perception loop keeps writing the latest ScreenObservation here; the
conversation loop reads it when the user says something. We only keep the most
recent observation plus a short ring buffer of recent ones so the Brain can
notice "the screen changed" without us re-sending every frame.
"""

from __future__ import annotations

import asyncio
from collections import deque

from .interfaces import ScreenObservation


class SharedScreenContext:
    def __init__(self, history: int = 8) -> None:
        self._latest: ScreenObservation | None = None
        self._recent: deque[ScreenObservation] = deque(maxlen=history)
        self._lock = asyncio.Lock()

    async def update(self, obs: ScreenObservation) -> None:
        async with self._lock:
            self._latest = obs
            self._recent.append(obs)

    async def latest(self) -> ScreenObservation | None:
        async with self._lock:
            return self._latest

    async def recent(self) -> list[ScreenObservation]:
        async with self._lock:
            return list(self._recent)
