"""
Pytest fixtures for Godot MCP integration tests.

Provides fixtures that create temporary Godot projects and initialize
the GodotServer instance for testing.
"""

import os
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
from typing import Generator

import pytest

# Godot official demo projects repository URL
GODOT_DEMO_PROJECTS_URL = "https://github.com/godotengine/godot-demo-projects.git"

# Add the parent directory to sys.path for imports
sys.path.insert(0, str(Path(__file__).parent.parent))

# Set GODOT_PATH for macOS if not already set
if sys.platform == "darwin" and not os.environ.get("GODOT_PATH"):
    mac_godot_path = "/Applications/Godot.app/Contents/MacOS/Godot"
    if Path(mac_godot_path).exists():
        os.environ["GODOT_PATH"] = mac_godot_path

from godot_mcp.server import GodotServer, godot_server


@pytest.fixture
def temp_godot_project() -> Generator[Path, None, None]:
    """
    Create a temporary Godot project directory with a valid project.godot file.

    Yields:
        Path: The path to the temporary Godot project directory.
    """
    # Create a temporary directory
    temp_dir = tempfile.mkdtemp(prefix="godot_mcp_test_")
    project_path = Path(temp_dir)

    # Create a minimal project.godot file
    project_godot_content = """; Engine configuration file.
; It's best edited using the editor UI and not directly,
; since the parameters that go here are not all obvious.
;
; Format:
;   [section] ; section goes first
;   param=value ; assign values to parameters

config_version=5

[application]

config/name="Test Project"
config/features=PackedStringArray("4.2", "Forward Plus")

[rendering]

renderer/rendering_method="gl_compatibility"
"""

    project_file = project_path / "project.godot"
    project_file.write_text(project_godot_content, encoding="utf-8")

    yield project_path

    # Cleanup: remove the temporary directory
    shutil.rmtree(temp_dir, ignore_errors=True)


@pytest.fixture
def godot_client() -> GodotServer:
    """
    Get the global GodotServer instance for testing.

    Returns:
        GodotServer: The global GodotServer instance.
    """
    return godot_server


@pytest.fixture
def temp_scene_file(temp_godot_project: Path) -> Path:
    """
    Create a temporary scene file with a Node2D root.

    Args:
        temp_godot_project: The temporary Godot project path.

    Returns:
        Path: The path to the created scene file (relative to project).
    """
    # Create a minimal .tscn file with Node2D root
    scene_content = """[gd_scene format=3 uid="uid://test123"]

[node name="root" type="Node2D"]
"""
    scene_path = temp_godot_project / "test_scene.tscn"
    scene_path.write_text(scene_content, encoding="utf-8")

    return Path("test_scene.tscn")


@pytest.fixture
def temp_script_file(temp_godot_project: Path) -> Path:
    """
    Create a temporary GDScript file for testing script attachment.

    Args:
        temp_godot_project: The temporary Godot project path.

    Returns:
        Path: The path to the created script file (relative to project).
    """
    script_content = """extends Node2D

func _ready():
    print("Test script loaded!")

func test_method():
    pass
"""
    script_path = temp_godot_project / "test_script.gd"
    script_path.write_text(script_content, encoding="utf-8")

    return Path("test_script.gd")


@pytest.fixture(scope="session")
def godot_demo_projects() -> Generator[Path, None, None]:
    """
    Clone the official Godot demo projects repository to a temporary directory.

    This fixture clones https://github.com/godotengine/godot-demo-projects.git
    into a temporary directory for testing. The repository is deleted after
    all tests in the session are complete.

    Note:
        This fixture uses session scope to avoid re-cloning for each test.
        The clone is shallow (depth=1) to minimize download time.

    Yields:
        Path: The path to the cloned Godot demo projects directory.

    Raises:
        pytest.skip: If git is not available or clone fails.
    """
    # Create a temporary directory for the clone
    temp_dir = tempfile.mkdtemp(prefix="godot_demo_projects_")
    clone_path = Path(temp_dir) / "godot-demo-projects"

    try:
        # Perform shallow clone for faster download
        result = subprocess.run(
            [
                "git",
                "clone",
                "--depth=1",
                GODOT_DEMO_PROJECTS_URL,
                str(clone_path),
            ],
            capture_output=True,
            text=True,
            timeout=300,  # 5 minutes timeout
        )

        if result.returncode != 0:
            shutil.rmtree(temp_dir, ignore_errors=True)
            pytest.skip(f"Failed to clone godot-demo-projects: {result.stderr}")

        yield clone_path

    except FileNotFoundError:
        shutil.rmtree(temp_dir, ignore_errors=True)
        pytest.skip("git is not installed or not in PATH")
    except subprocess.TimeoutExpired:
        shutil.rmtree(temp_dir, ignore_errors=True)
        pytest.skip("git clone timed out after 5 minutes")
    finally:
        # Cleanup: remove the temporary directory
        shutil.rmtree(temp_dir, ignore_errors=True)


@pytest.fixture
def demo_project_path(godot_demo_projects: Path) -> Generator[Path, None, None]:
    """
    Get a specific demo project from the cloned Godot demo projects.

    This is a helper fixture that provides access to the demo projects
    root directory. Tests can navigate to specific demo projects from here.

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

    Yields:
        Path: The path to the demo projects root directory.
    """
    yield godot_demo_projects
