"""
Configuration file for pytest.

Auto-imports:
    Add auto-imports for doctests.
    Currently, the following auto-imports are added:
    - `import numpy as np`

Markers:
    Markers are used to mark tests with certain properties.
    Currently, the following markers are defined:

    - plot: mark test that is uses matplotlib.pyplot.show.
      pyplot.show will be mocked if `--plot` is not used on the command line
    - slow: mark test as being slow.
      Run pytest with the `--slow` option to run slow tests.

    To mark a test with a marker, use the `@pytest.mark.<marker_name>` decorator.
"""

import logging
import unittest.mock
import warnings

import pytest

try:
    import matplotlib
except ModuleNotFoundError:
    matplotlib = None
try:
    import numpy as np
except ModuleNotFoundError:
    np = None


# Add auto-imports for doctests
if np is not None:

    @pytest.fixture(autouse=True)
    def add_np(doctest_namespace):
        doctest_namespace["np"] = np


# Patching plotting
@pytest.fixture(scope="session", autouse=True)
def default_session_fixture(request):
    log = logging.getLogger()
    log.info("Patching `show`")
    patch = unittest.mock.patch("matplotlib.pyplot.show")
    if matplotlib is not None:
        if not request.config.getoption("--plot"):
            patch.start()
    pyqtgraph_available = False
    try:
        import rna.plotting.backends.pyqtgraph  # noqa: F401

        pyqtgraph_available = True
    except ImportError:
        warnings.warn(
            "pyqtgraph is not installed. Install the 'pyqtgraph' extra to enable "
            "pyqtgraph plotting tests: pip install rna[pyqtgraph]",
            stacklevel=1,
        )
    if pyqtgraph_available and not request.config.getoption("--plot"):
        unittest.mock.patch("rna.plotting.backends.pyqtgraph.show").start()


def pytest_addoption(parser):
    if matplotlib is not None:
        parser.addoption("--plot", action="store_true", default=False, help="Activate plot tests")
    parser.addoption("--slow", action="store_true", default=False, help="Activate slow tests")


def pytest_configure(config):
    if matplotlib is not None:
        config.addinivalue_line("markers", "plot: mark test as requiring visual assertion by human")
    config.addinivalue_line("markers", "slow: mark test as slow")


def pytest_collection_modifyitems(config, items):
    skip_slow = pytest.mark.skip(reason="need --slow option to run")
    for item in items:
        if "slow" in item.keywords and not config.getoption("--slow"):
            item.add_marker(skip_slow)
