"""Conftest for the integration test layer.

The Unit-Suite in ``tests/conftest.py`` aggressively stubs ``fitz``,
``bs4``, ``openai`` and ``pydantic_settings`` so the 77 fast tests can
run without the full prod-requirements installed. That's the right
trade-off for unit tests but blocks every E2E case in this directory:
- ``fitz`` (PyMuPDF) is needed to read Wahlprogramm-PDF pages for
  citation verification (Sub-Issue D) and content plausibility (Sub-C)
- ``bs4`` (BeautifulSoup) is needed by the live NRWAdapter for HTML
  parsing of OPAL responses (Sub-Issue A)
- ``openai`` is needed by ``embeddings.create_embedding`` if a test
  ever wants to compute a query vector against the live DashScope API
- ``pydantic_settings`` provides the real ``Settings`` class with
  paths to the prod-DB and the embeddings-DB

This conftest does NOT replace those modules. It only sets up:

- The ``app`` package import path so ``from app.parlamente import ...``
  works when pytest is invoked from the webapp/ root
- A skip-on-import-error guard for tests that need a particular
  optional dep but don't want to crash the whole collection if it
  isn't installed locally

A test that runs in this directory must therefore have a real
``pip install -r requirements.txt -r requirements-dev.txt`` setup. The
``@pytest.mark.integration`` marker on every test in this directory
ensures the default ``pytest`` invocation skips them.
"""
import sys
from pathlib import Path

import pytest

# Make the `app` package importable when pytest is run from the webapp/ root.
ROOT = Path(__file__).resolve().parent.parent.parent
sys.path.insert(0, str(ROOT))


# The parent ``tests/conftest.py`` aggressively stubs ``fitz``, ``bs4``,
# ``openai`` and ``pydantic_settings`` in sys.modules so the unit suite
# can run without prod-requirements. Pytest loads parent conftests
# *first*, so by the time control reaches this file the stubs are
# already in place.
#
# For integration tests we want to use the *real* modules where they're
# installed. Strategy: per stubbed module, try to import the real one
# (after temporarily removing the stub from sys.modules). If the real
# module is available, keep it; if not, restore the stub so collection
# doesn't crash on import — individual tests that need the real module
# will skip via ``pytest.require_module(...)``.
_OPTIONAL_REAL_MODULES = ("fitz", "bs4", "openai", "pydantic_settings")
import importlib

_STUB_MODULES: dict[str, object] = {}
for _name in _OPTIONAL_REAL_MODULES:
    _stub = sys.modules.pop(_name, None)
    try:
        importlib.import_module(_name)
        # Real module found and now lives in sys.modules — drop the stub.
    except ImportError:
        # No real module available; restore the stub so unrelated
        # imports of e.g. ``app.embeddings`` (which does ``from openai
        # import OpenAI`` at module level) don't crash collection.
        if _stub is not None:
            sys.modules[_name] = _stub
        _STUB_MODULES[_name] = _stub
del _name, _stub, importlib


def _require(module_name: str) -> None:
    """Skip the calling test if an optional dependency isn't installed
    or is currently still represented by the parent-conftest stub.

    Use as ``pytest.require_module("fitz")`` at the top of a test that
    needs PyMuPDF.
    """
    if module_name in _STUB_MODULES:
        pytest.skip(
            f"integration test skipped: real {module_name!r} not installed "
            "in this environment (parent conftest stub still active)"
        )
    try:
        __import__(module_name)
    except ImportError as e:
        pytest.skip(f"integration test skipped: {module_name} not installed ({e})")


# Make the helper available on the pytest module namespace
pytest.require_module = _require  # type: ignore[attr-defined]


@pytest.fixture(scope="session")
def webapp_root() -> Path:
    """The webapp/ directory root, useful for resolving fixture paths."""
    return ROOT


@pytest.fixture(scope="session")
def referenzen_dir(webapp_root: Path) -> Path:
    """The static/referenzen directory containing all Wahlprogramm-PDFs."""
    return webapp_root / "app" / "static" / "referenzen"
