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

from unittest.mock import AsyncMock

import pytest

from ..connection_pool import ConnectionPool
from ..executor import Executor
from ..models import Backend, ResourceDescriptor, ResourceMapping


@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_uri, original_uri):
    return ResourceMapping(
        public_uri=public_uri,
        backend=backend,
        original_uri=original_uri,
        descriptor=ResourceDescriptor(uri=original_uri, name="x"),
    )


@pytest.mark.anyio
async def test_list_resources_returns_resources(backend, executor, pool):
    resources = await executor.list_resources(backend)
    uris = [str(r.uri) for r in resources]
    assert "test://greeting" in uris
    assert "test://config.json" in uris
    await pool.close_all()


@pytest.mark.anyio
async def test_read_resource_returns_text(backend, executor, pool):
    mapping = make_mapping(backend, "test://greeting", "test://greeting")
    result = await executor.read_resource(mapping)
    assert len(result.contents) == 1
    assert result.contents[0].text == "Hello from test server"
    await pool.close_all()


@pytest.mark.anyio
async def test_read_resource_uses_original_uri(backend, executor, pool):
    """Executor czyta po original_uri, nie public_uri."""
    mapping = make_mapping(backend, "public://renamed", "test://greeting")
    result = await executor.read_resource(mapping)
    assert result.contents[0].text == "Hello from test server"
    await pool.close_all()


@pytest.mark.anyio
async def test_subscribe_unsubscribe_call_session_methods():
    """Executor deleguje subscribe/unsubscribe do ClientSession z poprawnym URI."""
    fake_session = AsyncMock()
    fake_pool = AsyncMock()
    fake_pool.get = AsyncMock(return_value=fake_session)

    executor = Executor(fake_pool)
    backend = Backend(id="x", url="http://example/mcp")

    await executor.subscribe_resource(backend, "test://greeting")
    fake_session.subscribe_resource.assert_awaited_once()
    assert str(fake_session.subscribe_resource.await_args.args[0]) == "test://greeting"

    await executor.unsubscribe_resource(backend, "test://greeting")
    fake_session.unsubscribe_resource.assert_awaited_once()
    assert str(fake_session.unsubscribe_resource.await_args.args[0]) == "test://greeting"
