import os
import tempfile
import yaml
import numpy as np
import pytest
from astropy import units as u

from tardis.tests.tests_slow.report import DokuReport
from tardis.tests.tests_slow.plot_helpers import PlotUploader


def pytest_configure(config):
    integration_tests_configpath = config.getvalue("integration-tests")
    if integration_tests_configpath is not None:
        integration_tests_configpath = os.path.expandvars(
            os.path.expanduser(integration_tests_configpath)
        )
        config.option.integration_tests_config = yaml.load(
            open(integration_tests_configpath))

        # Used by DokuReport class to show build environment details in report.
        config._environment = []
        # prevent opening dokupath on slave nodes (xdist)
        if not hasattr(config, 'slaveinput'):
            config.dokureport = DokuReport(
                config.option.integration_tests_config['dokuwiki'])
            config.pluginmanager.register(config.dokureport)


def pytest_unconfigure(config):
    integration_tests_configpath = config.getvalue("integration-tests")
    if integration_tests_configpath is not None:
        config.pluginmanager.unregister(config.dokureport)


@pytest.mark.hookwrapper
def pytest_runtest_makereport(item, call):
    # execute all other hooks to obtain the report object
    outcome = yield
    report = outcome.get_result()
    if report.when == "call":
        if "plot_object" in item.fixturenames:
            plot_obj = item.funcargs["plot_object"]
            plot_obj.upload(report)
            report.extra = plot_obj.get_extras()


@pytest.fixture(scope="function")
def plot_object(request):
    return PlotUploader(request)


def setup_names():
    slow_tests_dir = os.path.dirname(os.path.realpath(__file__))
    names = list()
    for child in os.listdir(slow_tests_dir):
        if os.path.isdir(os.path.join(slow_tests_dir, child)):
            names.append(child)
    return names


@pytest.fixture(scope="class", params=setup_names())
def data_path(request):
    integration_tests_config = request.config.option.integration_tests_config

    return {
        'config_dirpath': os.path.join(
            os.path.dirname(os.path.realpath(__file__)), request.param
        ),
        'reference_dirpath': os.path.join(os.path.expandvars(
            os.path.expanduser(integration_tests_config["reference"])), request.param
        ),
        'setup_name': request.param
    }


@pytest.fixture(scope="class")
def reference(data_path):
    """
    Fixture to ingest reference data for slow test from already available
    compressed binaries (.npz). All data is collected in one dict and
    returned away.

    Assumed three compressed binaries (.npz) are placed in `slow-test-data/w7`
    directory, whose path is provided by command line argument:

    * ndarrays.npz                       | * quantities.npz
    Contents (all (.npy)):               | Contents (all (.npy)):
        * last_interaction_type          |     * t_rads
        * last_line_interaction_out_id   |     * luminosity_inner
        * last_line_interaction_in_id    |     * montecarlo_luminosity
        * j_estimators                   |     * montecarlo_virtual_luminousity
        * j_blue_estimators              |     * time_of_simulation
        * last_line_interaction_shell_id |     * montecarlo_nu
        * nubar_estimators               |     * last_line_interaction_angstrom
        * ws                             |     * j_blues_norm_factor

    * spectrum.npz
    Contents (all (.npy)):
        * luminosity_density_nu          | * wavelength
        * delta_frequency                | * luminosity_density_lambda
    """
    reference_dirpath = data_path['reference_dirpath']

    # TODO: make this fixture ingest data from an HDF5 file.
    ndarrays = dict(np.load(os.path.join(reference_dirpath, "ndarrays.npz")))
    quantities = dict(np.load(os.path.join(reference_dirpath, "quantities.npz")))
    spectrum = dict(np.load(os.path.join(reference_dirpath, "spectrum.npz")))

    # Associate CGS units to ndarrays of reference quantities.
    ndarrays.update(
        j_blues_norm_factor=
            u.Quantity(quantities['j_blues_norm_factor'], '1 / (cm2 s)'),
        last_line_interaction_angstrom=
            u.Quantity(quantities['last_line_interaction_angstrom'], 'Angstrom'),
        luminosity_inner=
            u.Quantity(quantities['luminosity_inner'], 'erg / s'),
        montecarlo_luminosity=
            u.Quantity(quantities['montecarlo_luminosity'], 'erg / s'),
        montecarlo_virtual_luminosity=
            u.Quantity(quantities['montecarlo_virtual_luminosity'], 'erg / s'),
        montecarlo_nu=
            u.Quantity(quantities['montecarlo_nu'], 'Hz'),
        t_rads=
            u.Quantity(quantities['t_rads'], 'K'),
        luminosity_density_nu=
            u.Quantity(spectrum['luminosity_density_nu'], 'erg'),
        delta_frequency=
            u.Quantity(spectrum['delta_frequency'], 'Hz'),
        wavelength=
            u.Quantity(spectrum['wavelength'], 'Angstrom'),
        luminosity_density_lambda=
            u.Quantity(spectrum['luminosity_density_lambda'], 'erg / (Angstrom s)'))
    return ndarrays

@@ -4,18 +4,20 @@
 ort 
-os
+glob
 %0Aimport 
 temp
@@ -16,16 +16,10 @@
 ort 
-tempfile
+os
 %0Aimp
@@ -1701,155 +1701,92 @@
 )%0A%0A%0A
-def setup_names():%0A    slow_tests_dir = os.path.dirname(os.path.realpath(__file__))%0A    names = list()%0A    for child in os.listdir(slow_tests_dir):
+@pytest.fixture(scope=%22class%22, params=%5B%0A    path for path in glob.glob(os.path.join(
 %0A   
@@ -1794,19 +1794,16 @@
     
-if 
 os.path.
 isdi
@@ -1802,13 +1802,15 @@
 ath.
-is
 dir
+name
 (os.
@@ -1818,140 +1818,59 @@
 ath.
-join(slow_tests_dir, child)):%0A            names.append(child)%0A    return names%0A%0A%0A@pytest.fixture(scope=%22class%22, params=setup_names()
+realpath(__file__)), %22*%22)) if os.path.isdir(path)%0A%5D
 )%0Ade
@@ -1973,118 +1973,95 @@
 fig%0A
-%0A
     
-return %7B%0A        'config_dirpath': os.path.join(%0A            os.path.dirname(os.path.realpath(__file__)),
+setup_name = os.path.basename(request.param)%0A    return %7B%0A        'config_dirpath':
  req
@@ -2066,34 +2066,24 @@
 equest.param
-%0A        )
 ,%0A        'r
@@ -2206,29 +2206,26 @@
 ce%22%5D)), 
-request.par
+setup_n
 am
+e
 %0A       
@@ -2250,29 +2250,26 @@
 _name': 
-request.par
+setup_n
 am
+e
 %0A    %7D%0A%0A

Replace setup_names method with a list comprehension.