"""Testy integracyjne Executor — wymagają działającego serwera MCP."""

import pytest

from ..connection_pool import ConnectionPool
from ..executor import Executor
from ..models import Backend, ToolDefinition, ToolMapping


@pytest.fixture
def backend(mcp_server_url):
    return Backend(id="test", url=mcp_server_url)


@pytest.fixture
def pool():
    return ConnectionPool()


@pytest.fixture
def executor(pool):
    return Executor(pool)


def make_mapping(backend, public_name, original_name):
    return ToolMapping(
        public_name=public_name,
        backend=backend,
        original_name=original_name,
        definition=ToolDefinition(name=original_name, description="", input_schema={}),
    )


@pytest.mark.anyio
async def test_list_tools_returns_tools(backend, executor, pool):
    tools = await executor.list_tools(backend)
    names = [t.name for t in tools]
    assert "echo" in names
    assert "add" in names
    await pool.close_all()


@pytest.mark.anyio
async def test_call_tool_echo(backend, executor, pool):
    mapping = make_mapping(backend, "echo", "echo")
    result = await executor.call_tool(mapping, {"message": "hello"})
    assert result.isError is False
    assert result.content[0].text == "hello"
    await pool.close_all()


@pytest.mark.anyio
async def test_call_tool_add(backend, executor, pool):
    mapping = make_mapping(backend, "add", "add")
    result = await executor.call_tool(mapping, {"a": 3, "b": 4})
    assert result.isError is False
    assert result.content[0].text == "7"
    await pool.close_all()


@pytest.mark.anyio
async def test_call_tool_uses_original_name(backend, executor, pool):
    """Executor używa original_name, nie public_name."""
    mapping = make_mapping(backend, "my_echo", "echo")
    result = await executor.call_tool(mapping, {"message": "test"})
    assert result.isError is False
    assert result.content[0].text == "test"
    await pool.close_all()


@pytest.mark.anyio
async def test_call_tool_error_is_returned(backend, executor, pool):
    """Narzędzie które rzuca wyjątek zwraca isError=True, nie propaguje wyjątku."""
    mapping = make_mapping(backend, "fail", "fail")
    result = await executor.call_tool(mapping, {})
    assert result.isError is True
    await pool.close_all()
