"""
Integration-style tests of the full HaloModel class.
"""
from halomod import TracerHaloModel, DMHaloModel
import pytest
import numpy as np

from hmf.halos.mass_definitions import MassDefinition
from hmf.density_field.filters import Filter
from halomod.profiles import Profile
from halomod.bias import Bias
from halomod.concentration import CMRelation
from halomod.hod import HOD


@pytest.mark.parametrize("model", (TracerHaloModel, DMHaloModel))
def test_default_actually_inits(model):
    model()


@pytest.fixture(scope="module")
def dmhm():
    return DMHaloModel()


@pytest.fixture(scope="module")
def thm():
    return TracerHaloModel(rmin=0.01, rmax=50, rnum=20)


def test_dm_model_instances(dmhm):
    assert isinstance(dmhm.mdef, MassDefinition)
    assert isinstance(dmhm.filter, Filter)
    assert isinstance(dmhm.halo_profile, Profile)
    assert isinstance(dmhm.bias, Bias)
    assert isinstance(dmhm.halo_concentration, CMRelation)


def test_tr_model_instances(thm):
    assert isinstance(thm.mdef, MassDefinition)
    assert isinstance(thm.filter, Filter)
    assert isinstance(thm.halo_profile, Profile)
    assert isinstance(thm.bias, Bias)
    assert isinstance(thm.halo_concentration, CMRelation)
    assert isinstance(thm.hod, HOD)


@pytest.mark.parametrize(
    "quantity",
    (
        "corr_linear_mm",
        "corr_halofit_mm",
        "corr_1h_auto_matter",
        "corr_2h_auto_matter",
        "corr_auto_matter",
        "corr_1h_ss_auto_tracer",
        "corr_1h_cs_auto_tracer",
        "corr_1h_auto_tracer",
        "corr_auto_tracer",
        "corr_1h_cross_tracer_matter",
        "corr_2h_cross_tracer_matter",
        "corr_cross_tracer_matter",
        "corr_2h_auto_tracer",
        # 'halo_profile_rho', 'halo_profile_lam', 'tracer_profile_rho', 'tracer_profile_lam')
    ),
)
def test_monotonic_dec(thm: TracerHaloModel, quantity):
    # Ensure it's going down (or potentially 1e-5 level numerical noise going up)
    assert np.all(np.diff(getattr(thm, quantity)) <= 1e-5)
