"""Tests for bus-level correlation (request-response via Futures)."""

import asyncio
import pytest
from nanobot.bus.queue import MessageBus
from nanobot.bus.events import OutboundMessage


@pytest.fixture
def bus():
    return MessageBus()


@pytest.mark.asyncio
async def test_register_correlation_returns_future(bus):
    future = bus.register_correlation("test-id-1")
    assert isinstance(future, asyncio.Future)
    assert not future.done()


@pytest.mark.asyncio
async def test_resolve_correlation_sets_future_result(bus):
    future = bus.register_correlation("test-id-1")
    msg = OutboundMessage(channel="hook", chat_id="test", content="hello", metadata={"correlation_id": "test-id-1"})
    bus.resolve_correlation(msg)
    assert future.done()
    assert future.result() == "hello"


@pytest.mark.asyncio
async def test_resolve_correlation_no_match_is_noop(bus):
    future = bus.register_correlation("test-id-1")
    msg = OutboundMessage(channel="hook", chat_id="test", content="hello", metadata={"correlation_id": "other-id"})
    bus.resolve_correlation(msg)
    assert not future.done()


@pytest.mark.asyncio
async def test_resolve_correlation_no_metadata_is_noop(bus):
    future = bus.register_correlation("test-id-1")
    msg = OutboundMessage(channel="hook", chat_id="test", content="hello")
    bus.resolve_correlation(msg)
    assert not future.done()


@pytest.mark.asyncio
async def test_resolve_correlation_cleans_up_store(bus):
    future = bus.register_correlation("test-id-1")
    msg = OutboundMessage(channel="hook", chat_id="test", content="hello", metadata={"correlation_id": "test-id-1"})
    bus.resolve_correlation(msg)
    assert "test-id-1" not in bus._correlation_store


@pytest.mark.asyncio
async def test_cancel_correlation(bus):
    future = bus.register_correlation("test-id-1")
    bus.cancel_correlation("test-id-1")
    assert "test-id-1" not in bus._correlation_store
    assert future.cancelled()
