"""
Integration tests for Input Map operations.

Tests the input map configuration features:
- input_setup_action: Configure input actions with key bindings
- input_list_actions: Read configured input actions
"""

import json
from pathlib import Path


from godot_mcp.server import (
    GodotServer,
    input_list_actions,
    input_setup_action,
)


class TestSetupInputMap:
    """Tests for the input_setup_action tool."""

    def test_input_setup_action_basic(
        self, temp_godot_project: Path, godot_client: GodotServer
    ) -> None:
        """Test setting up a basic input action with a single key."""
        result = input_setup_action(
            project_path=str(temp_godot_project),
            action_name="jump",
            keys=["Space"],
        )

        assert "successfully" in result.lower() or "jump" in result
        # Verify the action was added to project.godot
        project_file = temp_godot_project / "project.godot"
        content = project_file.read_text()
        # The action should appear in the project file
        assert "input/jump" in content or "jump" in result

    def test_input_setup_action_multiple_keys(
        self, temp_godot_project: Path, godot_client: GodotServer
    ) -> None:
        """Test setting up an input action with multiple key bindings."""
        result = input_setup_action(
            project_path=str(temp_godot_project),
            action_name="move_left",
            keys=["A", "Left"],
        )

        assert "successfully" in result.lower() or "move_left" in result

    def test_input_setup_action_with_modifiers(
        self, temp_godot_project: Path, godot_client: GodotServer
    ) -> None:
        """Test setting up an input action with modifier keys."""
        result = input_setup_action(
            project_path=str(temp_godot_project),
            action_name="save",
            keys=["Ctrl+S"],
        )

        assert "successfully" in result.lower() or "save" in result

    def test_input_setup_action_wasd(
        self, temp_godot_project: Path, godot_client: GodotServer
    ) -> None:
        """Test setting up WASD movement controls."""
        # Set up all four movement directions
        for action, keys in [
            ("move_up", ["W", "Up"]),
            ("move_down", ["S", "Down"]),
            ("move_left", ["A", "Left"]),
            ("move_right", ["D", "Right"]),
        ]:
            result = input_setup_action(
                project_path=str(temp_godot_project),
                action_name=action,
                keys=keys,
            )
            assert "fail" not in result.lower()

    def test_input_setup_action_invalid_project(self, temp_godot_project: Path) -> None:
        """Test that invalid project paths are rejected."""
        result = input_setup_action(
            project_path="/nonexistent/path",
            action_name="test",
            keys=["Space"],
        )

        assert "error" in result.lower() or "not a valid" in result.lower()


class TestListInputActions:
    """Tests for the input_list_actions tool (Read operation)."""

    def test_input_list_actions_empty(
        self, temp_godot_project: Path, godot_client: GodotServer
    ) -> None:
        """Test listing input actions on a fresh project."""
        result = input_list_actions(project_path=str(temp_godot_project))

        # Should return valid JSON or be empty for projects with no custom actions
        if result and result.strip():
            try:
                data = json.loads(result)
                assert "actions" in data
                assert "count" in data
            except json.JSONDecodeError:
                # If not JSON, it might be an error message or empty result
                # which is acceptable for a fresh project
                pass

    def test_input_list_actions_after_setup(
        self, temp_godot_project: Path, godot_client: GodotServer
    ) -> None:
        """Test listing input actions after setting up some actions."""
        # First set up some input actions
        input_setup_action(
            project_path=str(temp_godot_project),
            action_name="test_jump",
            keys=["Space"],
        )
        input_setup_action(
            project_path=str(temp_godot_project),
            action_name="test_fire",
            keys=["F", "Ctrl+F"],
        )

        # Now list them
        result = input_list_actions(project_path=str(temp_godot_project))

        # Should return valid JSON with our actions
        if result and result.strip():
            try:
                data = json.loads(result)
                assert "actions" in data
                # Find our actions in the list
                action_names = [a["name"] for a in data["actions"]]
                assert "test_jump" in action_names
                assert "test_fire" in action_names
            except json.JSONDecodeError:
                # If the result isn't JSON, verify the input map was at least set up
                # by checking the project.godot file
                project_content = (temp_godot_project / "project.godot").read_text()
                # Input actions are stored in [input] section as action_name={...}
                assert "test_jump=" in project_content
                assert "test_fire=" in project_content

    def test_input_list_actions_invalid_project(self) -> None:
        """Test that invalid project paths are rejected."""
        result = input_list_actions(project_path="/nonexistent/path")
        assert "error" in result.lower() or "not a valid" in result.lower()
