"""
E2E test fixtures for Docker-based Blender testing.
Manages Docker container lifecycle for real Blender tests.
"""

import pytest
import docker
import shutil
import zipfile
from pathlib import Path
import time


@pytest.fixture(scope="module")
def docker_client():
    """Provide Docker client for container management."""
    try:
        client = docker.from_env()
        # Verify Docker is running
        client.ping()
        return client
    except docker.errors.DockerException as e:
        pytest.skip(f"Docker not available: {e}")


@pytest.fixture(scope="module")
def blender_image(docker_client):
    """Build Blender Docker image if not exists."""
    image_tag = "text-texture-generator-e2e:latest"
    dockerfile_path = Path(__file__).parent / "docker"
    
    try:
        # Try to get existing image
        docker_client.images.get(image_tag)
        print(f"Using existing Docker image: {image_tag}")
    except docker.errors.ImageNotFound:
        print(f"Building Docker image: {image_tag}")
        # Build image
        docker_client.images.build(
            path=str(dockerfile_path),
            tag=image_tag,
            rm=True
        )
    
    return image_tag


@pytest.fixture(scope="function")
def blender_container(docker_client, blender_image, tmp_path):
    """
    Spin up Blender container for test execution.
    
    Yields container instance, cleans up after test.
    """
    container = None
    
    try:
        # Start container with addon mounted
        container = docker_client.containers.run(
            blender_image,
            command="/bin/sleep 3600",  # Keep alive for test duration
            detach=True,
            remove=False,  # We'll remove manually after cleanup
            volumes={
                str(tmp_path): {"bind": "/addon-test", "mode": "rw"}
            }
        )
        
        # Wait for container to be ready
        timeout = 10
        start = time.time()
        while time.time() - start < timeout:
            container.reload()
            if container.status == "running":
                break
            time.sleep(0.5)
        
        if container.status != "running":
            pytest.fail(f"Container failed to start: {container.status}")
        
        yield container
        
    finally:
        # Cleanup
        if container:
            try:
                container.stop(timeout=5)
                container.remove()
            except Exception as e:
                print(f"Warning: Container cleanup failed: {e}")


@pytest.fixture(scope="function")
def addon_package(tmp_path, request):
    """
    Package the addon as a zip file for installation in Blender.
    
    Detects version type from test file name and patches VERSION_TYPE accordingly.
    
    Returns path to the packaged addon zip.
    """
    src_dir = Path(__file__).parent.parent.parent / "src"
    
    # Determine version type from test module name
    test_file = request.node.fspath.basename
    version_type = "free" if "free_version" in test_file else "full"
    
    # Copy src to temp and patch constants.py
    temp_src = tmp_path / "src_temp"
    shutil.copytree(src_dir, temp_src)
    
    constants_file = temp_src / "utils" / "constants.py"
    content = constants_file.read_text()
    content = content.replace('VERSION_TYPE = "free"', f'VERSION_TYPE = "{version_type}"')
    constants_file.write_text(content)
    
    # Create zip from patched source
    addon_zip = tmp_path / "text_texture_generator.zip"
    with zipfile.ZipFile(addon_zip, 'w', zipfile.ZIP_DEFLATED) as zf:
        for file_path in temp_src.rglob("*"):
            if file_path.is_file():
                arc_name = f"text_texture_generator/{file_path.relative_to(temp_src)}"
                zf.write(file_path, arc_name)
    
    return addon_zip
