'''Base Ensemble Test module

Testing BaseEnsemble abstract class
'''

import os
import shutil
import pytest

from skrmt.ensemble.base_ensemble import BaseEnsemble
from skrmt.ensemble.gaussian_ensemble import GaussianEnsemble


TMP_DIR_PATH = os.path.join(os.getcwd(), "skrmt/ensemble/tests/tmp")


@pytest.fixture(scope="module", autouse=True)
def _setup_tmp_dir(request):
    '''Function that is run before all tests in this script.

    It creates a temporary folder in order to store useful files
    for the following tests.
    '''
    # if the directory already exists, it is deleted
    if os.path.exists(TMP_DIR_PATH):
        shutil.rmtree(TMP_DIR_PATH)
    # creating temporary directory
    os.mkdir(TMP_DIR_PATH)

    # specifying a function that will be run after all tests are completed
    request.addfinalizer(_remove_tmp_dir)


def _remove_tmp_dir():
    '''Function that removes the created temporary directory.

    The function is run when all tests in this module are completed.
    '''
    shutil.rmtree(TMP_DIR_PATH)


def test_init_exception():
    """Testing the abstract class cannot be instantiated
    """
    with pytest.raises(TypeError):
        _ = BaseEnsemble()  # pylint: disable=abstract-class-instantiated


def test_base_set_eigval_norm_const():
    """Testing setting a custom eigenvalue normalization constant
    """
    goe = GaussianEnsemble(beta=1, n=10, tridiagonal_form=False)

    assert goe.eigval_norm_const is not None

    goe._set_eigval_norm_const(100.0)  # pylint: disable=protected-access
    assert goe.eigval_norm_const == 100.0

    goe._set_eigval_norm_const(0.1)  # pylint: disable=protected-access
    assert goe.eigval_norm_const == 0.1


def test_base_ens_plot():
    """Testing plot eigval hist
    """
    fig_name = "test_base_ens_plot_eigval_hist.png"
    goe = GaussianEnsemble(beta=1, n=100, tridiagonal_form=False)
    goe.plot_eigval_hist(savefig_path=TMP_DIR_PATH+"/"+fig_name)
    assert os.path.isfile(os.path.join(TMP_DIR_PATH, fig_name))


def test_base_ens_eigval_hist_raises():
    """Testing raising an exception for invalid ``interval`` type.
    """
    goe = GaussianEnsemble(beta=1, n=10, tridiagonal_form=False)
    with pytest.raises(ValueError):
        goe.eigval_hist(bins=10, interval="invalid interval type")


def test_base_ens_plot_eigval_hist_raises():
    """Testing raising an exception for invalid ``interval`` type.
    """
    goe = GaussianEnsemble(beta=1, n=10, tridiagonal_form=False)
    with pytest.raises(ValueError):
        goe.plot_eigval_hist(bins=10, interval="invalid interval type")
