"""Tests for ui_map tool."""

from __future__ import annotations

import pytest
from unittest.mock import AsyncMock, patch

from godotiq.tools.bridge.ui_map import ui_map


class TestUiMapTool:
    @pytest.mark.asyncio
    async def test_default_params(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={
            "root": "root",
            "total_controls": 15,
            "interactive_elements": 5,
            "touch_targets_too_small": [],
            "layout": [],
        })
        with patch("godotiq.tools.bridge.ui_map.get_bridge", return_value=mock_bridge):
            result = await ui_map()
            mock_bridge.request.assert_called_once()
            params = mock_bridge.request.call_args[1]["params"]
            assert params["root"] == ""
            assert params["include_invisible"] is False
            assert params["max_depth"] == 10
            assert params["detail"] == "normal"
            assert result["total_controls"] == 15

    @pytest.mark.asyncio
    async def test_with_root(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={
            "root": "GameHUD",
            "total_controls": 12,
            "interactive_elements": 4,
            "layout": [{"name": "TopBar", "type": "HBoxContainer"}],
        })
        with patch("godotiq.tools.bridge.ui_map.get_bridge", return_value=mock_bridge):
            result = await ui_map(root="GameHUD")
            params = mock_bridge.request.call_args[1]["params"]
            assert params["root"] == "GameHUD"
            assert result["root"] == "GameHUD"

    @pytest.mark.asyncio
    async def test_touch_targets(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={
            "root": "GameHUD",
            "total_controls": 10,
            "interactive_elements": 3,
            "touch_targets_too_small": [
                {"node": "SmallBtn", "size": [30, 30], "min_recommended": [48, 48]},
            ],
            "layout": [],
        })
        with patch("godotiq.tools.bridge.ui_map.get_bridge", return_value=mock_bridge):
            result = await ui_map(root="GameHUD")
            assert len(result["touch_targets_too_small"]) == 1
            assert result["touch_targets_too_small"][0]["node"] == "SmallBtn"

    @pytest.mark.asyncio
    async def test_include_invisible(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={"total_controls": 20})
        with patch("godotiq.tools.bridge.ui_map.get_bridge", return_value=mock_bridge):
            await ui_map(include_invisible=True)
            params = mock_bridge.request.call_args[1]["params"]
            assert params["include_invisible"] is True

    @pytest.mark.asyncio
    async def test_detail_full(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={"total_controls": 5})
        with patch("godotiq.tools.bridge.ui_map.get_bridge", return_value=mock_bridge):
            await ui_map(detail="full")
            params = mock_bridge.request.call_args[1]["params"]
            assert params["detail"] == "full"

    @pytest.mark.asyncio
    async def test_timeout_value(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={})
        with patch("godotiq.tools.bridge.ui_map.get_bridge", return_value=mock_bridge):
            await ui_map()
            timeout = mock_bridge.request.call_args[1].get("timeout")
            assert timeout == 10.0

    @pytest.mark.asyncio
    async def test_max_depth(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={"total_controls": 3})
        with patch("godotiq.tools.bridge.ui_map.get_bridge", return_value=mock_bridge):
            await ui_map(max_depth=5)
            params = mock_bridge.request.call_args[1]["params"]
            assert params["max_depth"] == 5


class TestUiMapRegistration:
    def test_tool_registered(self):
        from godotiq.server import mcp
        tool_names = [t.name for t in mcp._tool_manager.list_tools()]
        assert "godotiq_ui_map" in tool_names
