import os
import tempfile
import importlib

import pytest

import astropy
import astropy.config.paths

# Force MPL to use non-gui backends for testing.
try:
    import matplotlib
except ImportError:
    pass
else:
    matplotlib.use('Agg')

# Don't actually import pytest_remotedata because that can do things to the
# entrypoints code in pytest.
remotedata_spec = importlib.util.find_spec("pytest_remotedata")
HAVE_REMOTEDATA = remotedata_spec is not None

# Do not collect the sample data file because this would download the sample data.
collect_ignore = ["data/sample.py"]


@pytest.fixture(scope='session', autouse=True)
def tmp_config_dir(request):
    """
    Globally set the default config for all tests.
    """
    tmpdir = tempfile.TemporaryDirectory()

    os.environ["SUNPY_CONFIGDIR"] = str(tmpdir.name)
    astropy.config.paths.set_temp_config._temp_path = str(tmpdir.name)
    astropy.config.paths.set_temp_cache._temp_path = str(tmpdir.name)

    yield

    del os.environ["SUNPY_CONFIGDIR"]
    tmpdir.cleanup()
    astropy.config.paths.set_temp_config._temp_path = None
    astropy.config.paths.set_temp_cache._temp_path = None


@pytest.fixture()
def sunpy_cache(mocker, tmp_path):
    """
    Provide a way to add local files to the cache. This can be useful when mocking
    remote requests.
    """
    from types import MethodType

    from sunpy.data.data_manager.cache import Cache
    from sunpy.data.data_manager.downloader import ParfiveDownloader
    from sunpy.data.data_manager.storage import InMemStorage
    cache = Cache(
        ParfiveDownloader(),
        InMemStorage(),
        tmp_path,
        None
    )

    def add(self, url, path):
        self._storage.store({
            'url': url,
            'file_path': path,
            'file_hash': 'none',  # hash doesn't matter
        })
    cache.add = MethodType(add, cache)

    def func(mocked):
        mocker.patch(mocked, cache)
        return cache
    yield func


@pytest.fixture()
def undo_config_dir_patch():
    """
    Provide a way for certain tests to not have the config dir.
    """
    oridir = os.environ["SUNPY_CONFIGDIR"]
    del os.environ["SUNPY_CONFIGDIR"]
    yield
    os.environ["SUNPY_CONFIGDIR"] = oridir


@pytest.fixture(scope='session', autouse=True)
def hide_parfive_progress(request):
    """
    Globally set the HIDE_PARFIVE_PROGESS to hide the parfive progress bar in tests.
    Used by the parfive helper class only.
    """
    os.environ["HIDE_PARFIVE_PROGESS"] = "True"
    yield
    del os.environ["HIDE_PARFIVE_PROGESS"]


@pytest.fixture(scope='session', autouse=True)
def tmp_dl_dir(request):
    """
    Globally set the default download directory for the test run to a tmp dir.
    """
    with tempfile.TemporaryDirectory() as tmpdir:
        os.environ["SUNPY_DOWNLOADDIR"] = tmpdir
        yield tmpdir
        del os.environ["SUNPY_DOWNLOADDIR"]


@pytest.fixture()
def undo_download_dir_patch():
    """
    Provide a way for certain tests to not have tmp download dir.
    """
    oridir = os.environ["SUNPY_DOWNLOADDIR"]
    del os.environ["SUNPY_DOWNLOADDIR"]
    yield
    os.environ["SUNPY_DOWNLOADDIR"] = oridir


def pytest_runtest_setup(item):
    """
    pytest hook to skip all tests that have the mark 'remotedata' if the
    pytest_remotedata plugin is not installed.
    """
    if isinstance(item, pytest.Function):
        if 'remote_data' in item.keywords and not HAVE_REMOTEDATA:
            pytest.skip("skipping remotedata tests as pytest-remotedata is not installed")

[((20, 18, 20, 63), 'importlib.util.find_spec', 'importlib.util.find_spec', ({(20, 43, 20, 62): '"""pytest_remotedata"""'}, {}), "('pytest_remotedata')", False, 'import importlib\n'), ((27, 1, 27, 46), 'pytest.fixture', 'pytest.fixture', (), '', False, 'import pytest\n'), ((46, 1, 46, 17), 'pytest.fixture', 'pytest.fixture', ({}, {}), '()', False, 'import pytest\n'), ((78, 1, 78, 17), 'pytest.fixture', 'pytest.fixture', ({}, {}), '()', False, 'import pytest\n'), ((89, 1, 89, 46), 'pytest.fixture', 'pytest.fixture', (), '', False, 'import pytest\n'), ((100, 1, 100, 46), 'pytest.fixture', 'pytest.fixture', (), '', False, 'import pytest\n'), ((111, 1, 111, 17), 'pytest.fixture', 'pytest.fixture', ({}, {}), '()', False, 'import pytest\n'), ((16, 4, 16, 25), 'matplotlib.use', 'matplotlib.use', ({(16, 19, 16, 24): '"""Agg"""'}, {}), "('Agg')", False, 'import matplotlib\n'), ((32, 13, 32, 42), 'tempfile.TemporaryDirectory', 'tempfile.TemporaryDirectory', ({}, {}), '()', False, 'import tempfile\n'), ((70, 16, 70, 38), 'types.MethodType', 'MethodType', ({(70, 27, 70, 30): 'add', (70, 32, 70, 37): 'cache'}, {}), '(add, cache)', False, 'from types import MethodType\n'), ((58, 8, 58, 27), 'sunpy.data.data_manager.downloader.ParfiveDownloader', 'ParfiveDownloader', ({}, {}), '()', False, 'from sunpy.data.data_manager.downloader import ParfiveDownloader\n'), ((59, 8, 59, 22), 'sunpy.data.data_manager.storage.InMemStorage', 'InMemStorage', ({}, {}), '()', False, 'from sunpy.data.data_manager.storage import InMemStorage\n'), ((105, 9, 105, 38), 'tempfile.TemporaryDirectory', 'tempfile.TemporaryDirectory', ({}, {}), '()', False, 'import tempfile\n'), ((129, 12, 129, 90), 'pytest.skip', 'pytest.skip', ({(129, 24, 129, 89): '"""skipping remotedata tests as pytest-remotedata is not installed"""'}, {}), "('skipping remotedata tests as pytest-remotedata is not installed')", False, 'import pytest\n')]