"""Tests for the Vastian message bus."""

import asyncio
import pytest

from vastian.bus import MessageBus, Message, MessageType, Priority


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


class TestMessageBus:
    def test_register_agent(self, bus: MessageBus) -> None:
        mailbox = bus.register_agent("liam")
        assert "liam" in bus.agent_ids
        assert isinstance(mailbox, asyncio.Queue)

    def test_register_team(self, bus: MessageBus) -> None:
        bus.register_agent("liam")
        bus.register_agent("elias")
        bus.register_team("vv-sync", ["liam", "elias"])
        assert "vv-sync" in bus.team_ids

    @pytest.mark.asyncio
    async def test_send_direct(self, bus: MessageBus) -> None:
        mailbox = bus.register_agent("charles")
        msg = Message(
            sender="user",
            recipient="charles",
            type=MessageType.QUERY,
            payload={"content": "What is the current status?"},
        )
        await bus.send(msg)
        received = await mailbox.get()
        assert received.id == msg.id
        assert received.payload["content"] == "What is the current status?"

    @pytest.mark.asyncio
    async def test_send_team_broadcast(self, bus: MessageBus) -> None:
        m1 = bus.register_agent("liam")
        m2 = bus.register_agent("elias")
        bus.register_team("vv-sync", ["liam", "elias"])

        msg = Message(
            sender="dominic",
            recipient="team:vv-sync",
            type=MessageType.BROADCAST,
            payload={"content": "Team update"},
        )
        await bus.send(msg)

        r1 = await m1.get()
        r2 = await m2.get()
        assert r1.payload["content"] == "Team update"
        assert r2.payload["content"] == "Team update"

    @pytest.mark.asyncio
    async def test_message_history(self, bus: MessageBus) -> None:
        bus.register_agent("charles")
        msg = Message(
            sender="user",
            recipient="charles",
            type=MessageType.QUERY,
            payload={"content": "test"},
        )
        await bus.send(msg)
        history = bus.get_history(sender="user")
        assert len(history) == 1
        assert history[0].id == msg.id

    def test_message_reply(self) -> None:
        original = Message(
            sender="user",
            recipient="charles",
            type=MessageType.QUERY,
            payload={"content": "hello"},
        )
        reply = original.reply(
            sender="charles",
            payload={"content": "hi there"},
        )
        assert reply.recipient == "user"
        assert reply.sender == "charles"
        assert reply.parent_id == original.id
        assert reply.thread_id == original.id
