"""``event_id`` → :class:`AgentSdkResponse`（被动应答缓存 + 超时清理）。

Java 版用一个守护线程定期扫描；Python 版做同样的事，但全部接口都同步可控，
``cleanup_once()`` 暴露出来便于单测验证。
"""

from __future__ import annotations

import threading
import time
from typing import Dict, Optional

from ..passive.base import AgentSdkResponse


_DEFAULT_TTL_MS = 120 * 1000  # 与 Java 一致：120 秒无更新即清理


class AgentSdkResponseMgr:
    _lock = threading.Lock()
    _event_id_to_response: Dict[str, AgentSdkResponse] = {}
    _ttl_ms: int = _DEFAULT_TTL_MS

    @classmethod
    def offer(cls, event_id: str, response: AgentSdkResponse) -> None:
        with cls._lock:
            cls._event_id_to_response[event_id] = response

    @classmethod
    def get(cls, event_id: str) -> Optional[AgentSdkResponse]:
        with cls._lock:
            return cls._event_id_to_response.get(event_id)

    @classmethod
    def remove(cls, event_id: str) -> None:
        with cls._lock:
            cls._event_id_to_response.pop(event_id, None)

    @classmethod
    def cleanup_once(cls, now_ms: Optional[int] = None) -> int:
        """删除所有 ``now - update_ts > ttl`` 的 response，返回删除条数。"""
        if now_ms is None:
            now_ms = int(time.time() * 1000)
        removed = 0
        with cls._lock:
            stale = [
                k for k, v in cls._event_id_to_response.items()
                if now_ms - v.update_ts > cls._ttl_ms
            ]
            for k in stale:
                cls._event_id_to_response.pop(k, None)
                removed += 1
        return removed

    @classmethod
    def set_ttl_ms_for_test(cls, ttl_ms: int) -> None:
        cls._ttl_ms = ttl_ms

    @classmethod
    def reset_ttl_for_test(cls) -> None:
        cls._ttl_ms = _DEFAULT_TTL_MS

    @classmethod
    def _reset_for_test(cls) -> None:
        with cls._lock:
            cls._event_id_to_response.clear()
