"""Sprint 0 Scaffolding Integration Tests.

Design Doc: docs/design/sprint-0-scaffolding.md
"""

import json

import pytest


class TestProjectStructureComplete:
    """INT-1: AC-1, AC-8 — Directory structure matches specification."""

    def test_ac1_ac8_project_structure_matches_specification(
        self, project_root
    ) -> None:
        # Required directories under src/godotiq/
        src = project_root / "src" / "godotiq"
        required_packages = [
            src,
            src / "parsers",
            src / "cache",
            src / "tools",
            src / "tools" / "bridge",
            src / "tools" / "spatial",
            src / "tools" / "code",
            src / "tools" / "animation",
            src / "tools" / "flow",
            src / "tools" / "assets",
            src / "tools" / "memory",
            src / "tools" / "ui",
            src / "tools" / "navigation",
        ]

        for pkg in required_packages:
            assert pkg.is_dir(), f"Missing directory: {pkg}"
            assert (pkg / "__init__.py").is_file(), (
                f"Missing __init__.py in {pkg}"
            )

        # Required source files
        source_files = [
            src / "server.py",
            src / "config.py",
            src / "parsers" / "tscn_parser.py",
            src / "parsers" / "gd_parser.py",
            src / "parsers" / "tres_parser.py",
            src / "cache" / "file_cache.py",
        ]
        for f in source_files:
            assert f.is_file(), f"Missing source file: {f}"

        # .gitkeep files
        gitkeep_dirs = [
            project_root / "tests" / "fixtures",
            project_root / "tests" / "test_parsers",
            project_root / "tests" / "test_tools",
            project_root / "godot-addon" / "addons" / "godotiq",
        ]
        for d in gitkeep_dirs:
            assert (d / ".gitkeep").is_file(), f"Missing .gitkeep in {d}"

        # Root config files
        root_files = [
            "pyproject.toml",
            ".gitignore",
            "CLAUDE.md",
            "README.md",
            ".godotiq.example.json",
            "LICENSE",
        ]
        for name in root_files:
            assert (project_root / name).is_file(), (
                f"Missing root file: {name}"
            )

        # .godotiq.example.json must be valid JSON
        example_config = project_root / ".godotiq.example.json"
        data = json.loads(example_config.read_text())
        assert "project" in data
        assert "conventions" in data


class TestAllModulesImportable:
    """INT-2: AC-2, AC-3 — All source modules import without error."""

    def test_ac2_ac3_all_source_modules_import_without_error(self) -> None:
        from godotiq.server import mcp, main
        from godotiq.parsers.tscn_parser import TscnNode, TscnScene, parse_tscn
        from godotiq.parsers.gd_parser import (
            GdSignal,
            GdFunction,
            GdScript,
            parse_gd,
        )
        from godotiq.parsers.tres_parser import parse_tres
        from godotiq.cache.file_cache import FileCache, CacheEntry
        from godotiq.config import load_config, GodotIQConfig

        # All 9 tool category packages
        import godotiq.tools.bridge
        import godotiq.tools.spatial
        import godotiq.tools.code
        import godotiq.tools.animation
        import godotiq.tools.flow
        import godotiq.tools.assets
        import godotiq.tools.memory
        import godotiq.tools.ui
        import godotiq.tools.navigation

        # Verify key symbols are callable/instantiable
        assert callable(main)
        assert callable(parse_tscn)
        assert callable(parse_gd)
        assert callable(parse_tres)
        assert callable(load_config)


class TestMcpServerPingToolRegistered:
    """INT-3: AC-3 — MCP server ping tool registered and responsive."""

    @pytest.mark.asyncio
    async def test_ac3_ping_tool_registered_and_returns_correct_response(
        self,
    ) -> None:
        from godotiq.server import mcp

        # List registered tools
        tools = await mcp.list_tools()
        tool_names = [t.name for t in tools]
        assert "godotiq_ping" in tool_names

        # Invoke the ping tool
        result = await mcp.call_tool("godotiq_ping", {})
        assert len(result) == 1
        payload = json.loads(result[0].text)
        from godotiq import __version__
        assert payload == {"status": "ok", "version": __version__, "license": "community"}

        # main() exists and is callable
        from godotiq.server import main

        assert callable(main)
