"""Tests for WsDeliveryManager and TerminalReplayStore.

Author: Vasiliy Zdanovskiy
email: vasilyvz@gmail.com
"""

from __future__ import annotations

import asyncio
import copy

import pytest

from mcp_proxy_adapter.core.delivery.terminal_replay_store import (
    TerminalReplayStore,
)
from mcp_proxy_adapter.core.delivery.ws_delivery_manager import WsDeliveryManager
from mcp_proxy_adapter.core.job_push.subscriptions import (
    Subscriber,
    SubscriberRegistry,
    SubscriptionCategory,
)


class RecordingSubscriber(Subscriber):
    """Subscriber that records sent payloads."""

    def __init__(self) -> None:
        self.sent: list[dict] = []

    async def send(self, payload: dict) -> None:
        self.sent.append(copy.deepcopy(payload))


def test_issue_ws_id_unique() -> None:
    """Two issue_ws_id calls return different non-empty strings."""
    registry = SubscriberRegistry()
    mgr = WsDeliveryManager(registry)
    a = mgr.issue_ws_id()
    b = mgr.issue_ws_id()
    assert a != b
    assert len(a) > 0
    assert len(b) > 0


@pytest.mark.asyncio
async def test_notify_reaches_ws_delivery_subscribers() -> None:
    """notify_terminal_delivery sends payload to WS_DELIVERY subscribers."""
    registry = SubscriberRegistry()
    sub = RecordingSubscriber()
    mgr = WsDeliveryManager(registry)
    ws_id = mgr.issue_ws_id()
    await registry.subscribe(ws_id, SubscriptionCategory.WS_DELIVERY, sub)
    payload = {"event": "delivery_completed", "job_id": "j1"}
    await mgr.notify_terminal_delivery(ws_id, payload)
    assert len(sub.sent) == 1
    assert sub.sent[0]["event"] == "delivery_completed"


@pytest.mark.asyncio
async def test_replay_after_terminal_before_subscribe() -> None:
    """Late subscriber receives terminal via flush_replay_to_subscriber."""
    registry = SubscriberRegistry()
    mgr = WsDeliveryManager(registry)
    ws_id = mgr.issue_ws_id()
    payload = {"event": "delivery_completed", "job_id": "j2"}
    await mgr.notify_terminal_delivery(ws_id, payload)
    late = RecordingSubscriber()
    await registry.subscribe(ws_id, SubscriptionCategory.WS_DELIVERY, late)
    await mgr.flush_replay_to_subscriber(ws_id, late)
    assert len(late.sent) >= 1
    assert late.sent[0]["job_id"] == "j2"


@pytest.mark.asyncio
async def test_ttl_eviction_optional() -> None:
    """Expired terminal returns None from get_terminal_copy."""
    store = TerminalReplayStore(ttl_seconds=0.01, max_entries=100)
    await store.store_terminal("w1", {"x": 1})
    await asyncio.sleep(0.05)
    result = await store.get_terminal_copy("w1")
    assert result is None
