"""
E2E tests for Project Settings tools.

Tests the project settings management tools using real Godot demo projects:
- project_setting_set
- project_setting_get
"""

from pathlib import Path


from godot_mcp.server import project_setting_get, project_setting_set


class TestGetProjectSetting:
    """E2E tests for project_setting_get tool (read-only)."""

    def test_get_project_name(self, any_demo_project: Path) -> None:
        """Test getting the project name from a demo project."""
        result = project_setting_get(
            project_path=str(any_demo_project),
            setting_key="application/config/name",
        )

        # Should return the project name
        assert isinstance(result, str)
        # Should not be an error
        if "error" not in result.lower():
            assert len(result) > 0

    def test_get_rendering_method(self, any_demo_project: Path) -> None:
        """Test getting the rendering method setting."""
        result = project_setting_get(
            project_path=str(any_demo_project),
            setting_key="rendering/renderer/rendering_method",
        )

        assert isinstance(result, str)

    def test_get_nonexistent_setting(self, any_demo_project: Path) -> None:
        """Test getting a setting that doesn't exist."""
        result = project_setting_get(
            project_path=str(any_demo_project),
            setting_key="nonexistent/setting/key",
        )

        # Should indicate not found or return empty/default
        assert isinstance(result, str)

    def test_get_project_features(self, any_demo_project: Path) -> None:
        """Test getting the project features array."""
        result = project_setting_get(
            project_path=str(any_demo_project),
            setting_key="application/config/features",
        )

        assert isinstance(result, str)


class TestSetProjectSetting:
    """E2E tests for project_setting_set tool (requires copy)."""

    def test_set_viewport_width(self, demo_project_copy: Path) -> None:
        """Test setting the viewport width on a demo project copy."""
        result = project_setting_set(
            project_path=str(demo_project_copy),
            setting_key="display/window/size/viewport_width",
            setting_value=1920,
        )

        assert "successfully" in result.lower() or "set" in result.lower(), (
            f"project_setting_set failed: {result}"
        )

        # Verify the setting was saved
        project_file = demo_project_copy / "project.godot"
        content = project_file.read_text(encoding="utf-8")
        assert "1920" in content

    def test_set_viewport_height(self, demo_project_copy: Path) -> None:
        """Test setting the viewport height on a demo project copy."""
        result = project_setting_set(
            project_path=str(demo_project_copy),
            setting_key="display/window/size/viewport_height",
            setting_value=1080,
        )

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

    def test_set_and_get_setting(self, demo_project_copy: Path) -> None:
        """Test setting a value and reading it back."""
        # Set a custom setting
        set_result = project_setting_set(
            project_path=str(demo_project_copy),
            setting_key="display/window/size/viewport_width",
            setting_value=1280,
        )
        assert "successfully" in set_result.lower() or "set" in set_result.lower()

        # Read it back
        get_result = project_setting_get(
            project_path=str(demo_project_copy),
            setting_key="display/window/size/viewport_width",
        )
        assert "1280" in get_result

    def test_set_string_setting(self, demo_project_copy: Path) -> None:
        """Test setting a string value."""
        result = project_setting_set(
            project_path=str(demo_project_copy),
            setting_key="application/config/description",
            setting_value="E2E Test Description",
        )

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

    def test_set_boolean_setting(self, demo_project_copy: Path) -> None:
        """Test setting a boolean value."""
        result = project_setting_set(
            project_path=str(demo_project_copy),
            setting_key="display/window/size/resizable",
            setting_value=False,
        )

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

    def test_modify_existing_setting(self, demo_project_copy: Path) -> None:
        """Test modifying an existing setting in the demo project."""
        # First get the current name
        original = project_setting_get(
            project_path=str(demo_project_copy),
            setting_key="application/config/name",
        )

        # Change it
        result = project_setting_set(
            project_path=str(demo_project_copy),
            setting_key="application/config/name",
            setting_value="Modified Demo Name",
        )

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

        # Verify it changed
        new_value = project_setting_get(
            project_path=str(demo_project_copy),
            setting_key="application/config/name",
        )
        assert "Modified Demo Name" in new_value


class TestProjectSettingsPreserveFormat:
    """Tests to ensure project settings modifications preserve file format."""

    def test_preserve_other_settings(self, demo_project_copy: Path) -> None:
        """Test that modifying one setting preserves others."""
        project_file = demo_project_copy / "project.godot"
        original_content = project_file.read_text(encoding="utf-8")

        # Modify a setting
        project_setting_set(
            project_path=str(demo_project_copy),
            setting_key="display/window/size/viewport_width",
            setting_value=1920,
        )

        new_content = project_file.read_text(encoding="utf-8")

        # Original project name should still be present
        assert "config/name" in new_content

    def test_preserve_sections(self, demo_project_copy: Path) -> None:
        """Test that file sections are preserved after modification."""
        project_file = demo_project_copy / "project.godot"
        original_content = project_file.read_text(encoding="utf-8")

        # Check original has sections
        assert "[application]" in original_content or "application" in original_content

        # Modify a setting
        project_setting_set(
            project_path=str(demo_project_copy),
            setting_key="display/window/size/viewport_width",
            setting_value=1920,
        )

        new_content = project_file.read_text(encoding="utf-8")

        # Sections should still exist
        assert "[application]" in new_content or "application" in new_content
