from __future__ import annotations

import pytest

from mcp.server.fastmcp import FastMCP
from mrp.models import CapabilitiesResult, CapabilityInfo

from mrp_mcp.tools.discovery import register


@pytest.fixture
def mcp_server(mock_agent, state):
    mcp = FastMCP("test")
    register(mcp, mock_agent, state)
    return mcp


@pytest.mark.asyncio
async def test_discover_finds_agents(mcp_server, mock_agent, state):
    result = await mcp_server.call_tool("mrp_discover", {"capability": "text:translate"})
    text = result[0][0].text

    mock_agent.discover_search.assert_called_once_with(
        capabilities=["text:translate"],
        capability_prefix=None,
        name=None,
    )
    assert "TranslatorBot" in text
    assert "Found 1 agent(s)" in text
    assert "text:translate" in text
    # Agent should be added to contacts
    assert len(state.contacts) == 1
    assert "translatorbot" in state.aliases


@pytest.mark.asyncio
async def test_discover_by_prefix(mcp_server, mock_agent, state):
    result = await mcp_server.call_tool("mrp_discover", {"capability_prefix": "text:"})
    text = result[0][0].text

    mock_agent.discover_search.assert_called_once_with(
        capabilities=None,
        capability_prefix="text:",
        name=None,
    )
    assert "Found 1 agent(s)" in text


@pytest.mark.asyncio
async def test_discover_by_name(mcp_server, mock_agent, state):
    result = await mcp_server.call_tool("mrp_discover", {"name": "translator"})
    text = result[0][0].text

    mock_agent.discover_search.assert_called_once_with(
        capabilities=None,
        capability_prefix=None,
        name="translator",
    )
    assert "Found 1 agent(s)" in text


@pytest.mark.asyncio
async def test_discover_no_params(mcp_server, mock_agent):
    result = await mcp_server.call_tool("mrp_discover", {})
    text = result[0][0].text

    assert "Error" in text
    mock_agent.discover_search.assert_not_called()


@pytest.mark.asyncio
async def test_discover_no_results(mcp_server, mock_agent):
    mock_agent.discover_search.return_value = []
    result = await mcp_server.call_tool("mrp_discover", {"capability": "nonexistent"})
    text = result[0][0].text

    assert "No agents found" in text


@pytest.mark.asyncio
async def test_list_contacts_empty(mcp_server):
    result = await mcp_server.call_tool("mrp_list_contacts", {})
    text = result[0][0].text

    assert "No contacts yet" in text


@pytest.mark.asyncio
async def test_list_contacts_with_agents(mcp_server, state, sample_agents):
    for agent in sample_agents:
        state.add_contact(agent)

    result = await mcp_server.call_tool("mrp_list_contacts", {})
    text = result[0][0].text

    assert "Agent Alpha" in text
    assert "Agent Beta" in text
    assert "text:chat" in text
    assert "code:review" in text


@pytest.mark.asyncio
async def test_capabilities(mcp_server, mock_agent):
    mock_agent.list_capabilities.return_value = CapabilitiesResult(
        capabilities=[
            CapabilityInfo(tag="text:translate", agent_count=5),
            CapabilityInfo(tag="code:review", agent_count=2),
        ]
    )

    result = await mcp_server.call_tool("mrp_capabilities", {})
    text = result[0][0].text

    assert "text:translate" in text
    assert "5 agents" in text
    assert "code:review" in text
    assert "2 agents" in text


@pytest.mark.asyncio
async def test_capabilities_empty(mcp_server, mock_agent):
    mock_agent.list_capabilities.return_value = CapabilitiesResult(capabilities=[])

    result = await mcp_server.call_tool("mrp_capabilities", {})
    text = result[0][0].text

    assert "No capabilities" in text
