"""Tests for extended ToolsResource parameters (bundle_id, agent_id, server_ids)."""

from __future__ import annotations

from typing import Any
from unittest.mock import AsyncMock
from uuid import uuid4

import pytest

from mcpgateway_sdk.resources.tools import ToolsResource


@pytest.fixture
def http() -> AsyncMock:
    """Mock HTTPClient."""
    return AsyncMock()


@pytest.fixture
def tools(http: AsyncMock) -> ToolsResource:
    """ToolsResource with mocked HTTP."""
    return ToolsResource(http)


def _execute_result_data() -> dict[str, Any]:
    return {
        "result": {"ok": True},
        "server_id": str(uuid4()),
        "tool_name": "test_tool",
        "duration_ms": 100,
        "error": None,
    }


class TestSearchWithBundleId:
    """Tests for search with bundle_id parameter."""

    async def test_includes_bundle_id_in_body(self, tools: ToolsResource, http: AsyncMock) -> None:
        bid = uuid4()
        http.request.return_value = {"tools": []}

        await tools.search("weather", bundle_id=bid)

        body = http.request.call_args.kwargs["json"]
        assert body["bundle_id"] == str(bid)

    async def test_includes_agent_id_in_body(self, tools: ToolsResource, http: AsyncMock) -> None:
        aid = uuid4()
        http.request.return_value = {"tools": []}

        await tools.search("weather", agent_id=aid)

        body = http.request.call_args.kwargs["json"]
        assert body["agent_id"] == str(aid)

    async def test_includes_server_ids_in_body(self, tools: ToolsResource, http: AsyncMock) -> None:
        sid1, sid2 = uuid4(), uuid4()
        http.request.return_value = {"tools": []}

        await tools.search("weather", server_ids=[sid1, sid2])

        body = http.request.call_args.kwargs["json"]
        assert body["server_ids"] == [str(sid1), str(sid2)]

    async def test_omits_none_params(self, tools: ToolsResource, http: AsyncMock) -> None:
        http.request.return_value = {"tools": []}

        await tools.search("weather")

        body = http.request.call_args.kwargs["json"]
        assert "bundle_id" not in body
        assert "agent_id" not in body
        assert "server_ids" not in body


class TestExecuteWithBundleId:
    """Tests for execute with bundle_id/agent_id parameters."""

    async def test_includes_bundle_id_in_body(self, tools: ToolsResource, http: AsyncMock) -> None:
        bid = uuid4()
        http.request.return_value = _execute_result_data()

        await tools.execute("test_tool", server_name="srv", bundle_id=bid)

        body = http.request.call_args.kwargs["json"]
        assert body["bundle_id"] == str(bid)

    async def test_includes_agent_id_in_body(self, tools: ToolsResource, http: AsyncMock) -> None:
        aid = uuid4()
        http.request.return_value = _execute_result_data()

        await tools.execute("test_tool", server_name="srv", agent_id=aid)

        body = http.request.call_args.kwargs["json"]
        assert body["agent_id"] == str(aid)

    async def test_omits_none_params(self, tools: ToolsResource, http: AsyncMock) -> None:
        http.request.return_value = _execute_result_data()

        await tools.execute("test_tool", server_name="srv")

        body = http.request.call_args.kwargs["json"]
        assert "bundle_id" not in body
        assert "agent_id" not in body
