"""Shared conftest for all integration tests."""

import os
import re
from pathlib import Path

import pytest

from reflex.testing import AppHarness, AppHarnessProd

DISPLAY = None
XVFB_DIMENSIONS = (800, 600)


@pytest.fixture(scope="session", autouse=True)
def xvfb():
    """Create virtual X display.

    This function is a no-op unless GITHUB_ACTIONS is set in the environment.

    Yields:
        the pyvirtualdisplay object that the browser will be open on
    """
    if os.environ.get("GITHUB_ACTIONS") and not os.environ.get("APP_HARNESS_HEADLESS"):
        from pyvirtualdisplay.smartdisplay import (  # pyright: ignore [reportMissingImports]
            SmartDisplay,
        )

        global DISPLAY
        with SmartDisplay(visible=False, size=XVFB_DIMENSIONS) as DISPLAY:
            yield DISPLAY
        DISPLAY = None
    else:
        yield None


def pytest_exception_interact(node, call, report):
    """Take and upload screenshot when tests fail.

    Args:
        node: The pytest item that failed.
        call: The pytest call describing when/where the test was invoked.
        report: The pytest log report object.
    """
    screenshot_dir = os.environ.get("SCREENSHOT_DIR")
    if DISPLAY is None or screenshot_dir is None:
        return

    screenshot_dir = Path(screenshot_dir)
    screenshot_dir.mkdir(parents=True, exist_ok=True)
    safe_filename = re.sub(
        r"(?u)[^-\w.]",
        "_",
        str(node.nodeid).strip().replace(" ", "_").replace(":", "_").replace(".py", ""),
    )

    try:
        DISPLAY.waitgrab().save(
            (Path(screenshot_dir) / safe_filename).with_suffix(".png"),
        )
    except Exception as e:
        print(f"Failed to take screenshot for {node}: {e}")


@pytest.fixture(
    scope="session", params=[AppHarness, AppHarnessProd], ids=["dev", "prod"]
)
def app_harness_env(request):
    """Parametrize the AppHarness class to use for the test, either dev or prod.

    Args:
        request: The pytest fixture request object.

    Returns:
        The AppHarness class to use for the test.
    """
    return request.param
