"""
Pytest fixtures for Godot MCP E2E tests.

Provides fixtures that select specific demo projects from the cloned
godot-demo-projects repository for testing.
"""

import shutil
from pathlib import Path
from typing import Generator

import pytest


@pytest.fixture
def demo_2d_platformer(godot_demo_projects: Path) -> Generator[Path, None, None]:
    """
    Get the 2D Platformer demo project for testing.

    This is a classic 2D platformer game demo that contains:
    - TileMap usage
    - Player scripts
    - Input handling
    - Scene structure

    Args:
        godot_demo_projects: The path to the cloned demo projects repository.

    Yields:
        Path: The path to the 2D Platformer demo project.
    """
    project_path = godot_demo_projects / "2d" / "platformer"
    if not (project_path / "project.godot").exists():
        pytest.skip("2D Platformer demo project not found")
    yield project_path


@pytest.fixture
def demo_3d_platformer(godot_demo_projects: Path) -> Generator[Path, None, None]:
    """
    Get the 3D Platformer demo project for testing.

    This is a 3D platformer game demo that contains:
    - 3D scenes and nodes
    - Materials
    - Player controller scripts

    Args:
        godot_demo_projects: The path to the cloned demo projects repository.

    Yields:
        Path: The path to the 3D Platformer demo project.
    """
    project_path = godot_demo_projects / "3d" / "platformer"
    if not (project_path / "project.godot").exists():
        pytest.skip("3D Platformer demo project not found")
    yield project_path


@pytest.fixture
def demo_dodge_the_creeps(godot_demo_projects: Path) -> Generator[Path, None, None]:
    """
    Get the Dodge the Creeps demo project for testing.

    This is the official "Your First 2D Game" tutorial project that contains:
    - Basic scene structure
    - Simple scripts
    - Signal connections
    - Input handling

    Args:
        godot_demo_projects: The path to the cloned demo projects repository.

    Yields:
        Path: The path to the Dodge the Creeps demo project.
    """
    project_path = godot_demo_projects / "2d" / "dodge_the_creeps"
    if not (project_path / "project.godot").exists():
        pytest.skip("Dodge the Creeps demo project not found")
    yield project_path


@pytest.fixture
def demo_tps(godot_demo_projects: Path) -> Generator[Path, None, None]:
    """
    Get the Third Person Shooter demo project for testing.

    This is a 3D TPS demo that contains:
    - Complex 3D scenes
    - Materials and shaders
    - Input mapping
    - Character controller

    Args:
        godot_demo_projects: The path to the cloned demo projects repository.

    Yields:
        Path: The path to the TPS demo project.
    """
    project_path = godot_demo_projects / "3d" / "tps_demo"
    if not (project_path / "project.godot").exists():
        # Try alternative path
        project_path = godot_demo_projects / "3d" / "third_person_shooter"
        if not (project_path / "project.godot").exists():
            pytest.skip("TPS demo project not found")
    yield project_path


@pytest.fixture
def demo_gui_controls(godot_demo_projects: Path) -> Generator[Path, None, None]:
    """
    Get the GUI Controls demo project for testing.

    This demo contains various UI control nodes useful for testing
    signal connections and UI-related operations.

    Args:
        godot_demo_projects: The path to the cloned demo projects repository.

    Yields:
        Path: The path to the GUI Controls demo project.
    """
    project_path = godot_demo_projects / "gui" / "control_gallery"
    if not (project_path / "project.godot").exists():
        pytest.skip("GUI Controls demo project not found")
    yield project_path


@pytest.fixture
def any_demo_project(godot_demo_projects: Path) -> Generator[Path, None, None]:
    """
    Get any available demo project for basic testing.

    This fixture searches for the first available demo project with
    a valid project.godot file.

    Args:
        godot_demo_projects: The path to the cloned demo projects repository.

    Yields:
        Path: The path to any available demo project.
    """
    # Priority list of demo projects to try
    candidates = [
        godot_demo_projects / "2d" / "dodge_the_creeps",
        godot_demo_projects / "2d" / "platformer",
        godot_demo_projects / "3d" / "platformer",
        godot_demo_projects / "gui" / "control_gallery",
    ]

    for candidate in candidates:
        if (candidate / "project.godot").exists():
            yield candidate
            return

    # If none found, search recursively
    for project_godot in godot_demo_projects.rglob("project.godot"):
        yield project_godot.parent
        return

    pytest.skip("No demo project found")


@pytest.fixture
def demo_project_copy(any_demo_project: Path, tmp_path: Path) -> Generator[Path, None, None]:
    """
    Create a temporary copy of a demo project for destructive tests.

    This fixture copies a demo project to a temporary directory so that
    tests can modify it without affecting the original.

    Args:
        any_demo_project: The path to any available demo project.
        tmp_path: Pytest's temporary path fixture.

    Yields:
        Path: The path to the copied demo project.
    """
    # Copy the project to tmp_path
    dest = tmp_path / any_demo_project.name
    shutil.copytree(any_demo_project, dest)
    yield dest
    # Cleanup is automatic via tmp_path


@pytest.fixture
def demo_2d_copy(demo_2d_platformer: Path, tmp_path: Path) -> Generator[Path, None, None]:
    """
    Create a temporary copy of the 2D Platformer demo for destructive tests.

    Args:
        demo_2d_platformer: The 2D Platformer demo project path.
        tmp_path: Pytest's temporary path fixture.

    Yields:
        Path: The path to the copied demo project.
    """
    dest = tmp_path / demo_2d_platformer.name
    shutil.copytree(demo_2d_platformer, dest)
    yield dest


@pytest.fixture
def demo_3d_copy(demo_3d_platformer: Path, tmp_path: Path) -> Generator[Path, None, None]:
    """
    Create a temporary copy of the 3D Platformer demo for destructive tests.

    Args:
        demo_3d_platformer: The 3D Platformer demo project path.
        tmp_path: Pytest's temporary path fixture.

    Yields:
        Path: The path to the copied demo project.
    """
    dest = tmp_path / demo_3d_platformer.name
    shutil.copytree(demo_3d_platformer, dest)
    yield dest
