"""Tests for state inspection tool."""

import pytest
from unittest.mock import AsyncMock, patch

from godotiq.tools.bridge.state_inspect import state_inspect


class TestStateInspectTool:
    @pytest.mark.asyncio
    async def test_no_queries(self):
        result = await state_inspect()
        assert "error" in result

    @pytest.mark.asyncio
    async def test_empty_queries(self):
        result = await state_inspect(queries=[])
        assert "error" in result

    @pytest.mark.asyncio
    async def test_autoload_query(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={
            "results": [{
                "node": "EconomyManager",
                "found": True,
                "class": "Node",
                "properties": {"cash": 1250.0, "daily_income": 320.5},
            }],
        })
        with patch("godotiq.tools.bridge.state_inspect.get_bridge", return_value=mock_bridge):
            result = await state_inspect(queries=[
                {"autoload": "EconomyManager", "properties": ["cash", "daily_income"]},
            ])
            assert result["results"][0]["found"] is True
            assert result["results"][0]["properties"]["cash"] == 1250.0

    @pytest.mark.asyncio
    async def test_node_path_query(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={
            "results": [{
                "node": "Worker_1",
                "found": True,
                "class": "Node3D",
                "properties": {
                    "state": "WALKING",
                    "global_position": [1.2, 0, -0.5],
                },
            }],
        })
        with patch("godotiq.tools.bridge.state_inspect.get_bridge", return_value=mock_bridge):
            result = await state_inspect(queries=[
                {"node": "/root/Main/Entities/Worker_1", "properties": ["state", "global_position"]},
            ])
            assert result["results"][0]["properties"]["state"] == "WALKING"

    @pytest.mark.asyncio
    async def test_node_not_found(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={
            "results": [{
                "node": "NonExistent",
                "found": False,
                "error": "Node not found",
            }],
        })
        with patch("godotiq.tools.bridge.state_inspect.get_bridge", return_value=mock_bridge):
            result = await state_inspect(queries=[
                {"autoload": "NonExistent", "properties": ["foo"]},
            ])
            assert result["results"][0]["found"] is False

    @pytest.mark.asyncio
    async def test_multiple_queries(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={
            "results": [
                {"node": "GameManager", "found": True, "properties": {"current_day": 15}},
                {"node": "EconomyManager", "found": True, "properties": {"cash": 500}},
            ],
        })
        with patch("godotiq.tools.bridge.state_inspect.get_bridge", return_value=mock_bridge):
            result = await state_inspect(queries=[
                {"autoload": "GameManager", "properties": ["current_day"]},
                {"autoload": "EconomyManager", "properties": ["cash"]},
            ])
            assert len(result["results"]) == 2
            assert result["results"][0]["properties"]["current_day"] == 15

    @pytest.mark.asyncio
    async def test_method_call_property(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={
            "results": [{
                "node": "OrderManager",
                "found": True,
                "class": "Node",
                "properties": {"pending_orders.size()": 5},
            }],
        })
        with patch("godotiq.tools.bridge.state_inspect.get_bridge", return_value=mock_bridge):
            result = await state_inspect(queries=[
                {"autoload": "OrderManager", "properties": ["pending_orders.size()"]},
            ])
            assert result["results"][0]["properties"]["pending_orders.size()"] == 5

    @pytest.mark.asyncio
    async def test_timeout_value(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={"results": []})
        with patch("godotiq.tools.bridge.state_inspect.get_bridge", return_value=mock_bridge):
            await state_inspect(queries=[{"autoload": "GM", "properties": ["x"]}])
            call_kwargs = mock_bridge.request.call_args
            assert call_kwargs.kwargs.get("timeout") == 5.0 or call_kwargs[1].get("timeout") == 5.0

    @pytest.mark.asyncio
    async def test_params_passed_correctly(self):
        mock_bridge = AsyncMock()
        mock_bridge.request = AsyncMock(return_value={"results": []})
        with patch("godotiq.tools.bridge.state_inspect.get_bridge", return_value=mock_bridge):
            queries = [
                {"autoload": "GM", "properties": ["day"]},
                {"node": "/root/Main/Player", "properties": ["hp"]},
            ]
            await state_inspect(queries=queries)
            call_args = mock_bridge.request.call_args
            assert call_args[0][0] == "state_inspect"
            assert call_args[1]["params"]["queries"] == queries
