"""Tests for p-value multiple-testing correction against R references."""
import numpy as np
import pytest

from activepathways import p_adjust


# R reference: p.adjust(c(0.01, 0.05, 0.1, 0.5), method="holm")
PVALS = np.array([0.01, 0.05, 0.1, 0.5])


def test_holm_r_reference():
    expected = np.array([0.04, 0.15, 0.20, 0.50])
    result = p_adjust(PVALS, "holm")
    np.testing.assert_allclose(result, expected, atol=1e-6)


def test_bonferroni_r_reference():
    # p.adjust(c(0.01,0.05,0.1,0.5), "bonferroni") = c(0.04, 0.20, 0.40, 1.0)
    expected = np.array([0.04, 0.20, 0.40, 1.0])
    result = p_adjust(PVALS, "bonferroni")
    np.testing.assert_allclose(result, expected, atol=1e-6)


def test_bh_r_reference():
    # p.adjust(c(0.01,0.05,0.1,0.5), "BH") = c(0.04, 0.10, 0.133333, 0.5)
    expected = np.array([0.04, 0.10, 0.1333333, 0.5])
    result = p_adjust(PVALS, "BH")
    np.testing.assert_allclose(result, expected, atol=1e-5)


def test_fdr_alias_equals_bh():
    result_bh = p_adjust(PVALS, "BH")
    result_fdr = p_adjust(PVALS, "fdr")
    np.testing.assert_array_equal(result_bh, result_fdr)


def test_none_returns_unchanged():
    result = p_adjust(PVALS, "none")
    np.testing.assert_array_equal(result, PVALS)


def test_adjusted_values_capped_at_one():
    big = np.array([0.9, 0.95, 0.99])
    result = p_adjust(big, "bonferroni")
    assert np.all(result <= 1.0)


def test_result_length_matches_input():
    p = np.array([0.01, 0.02, 0.03, 0.04, 0.05])
    for method in ("holm", "bonferroni", "BH", "BY", "hochberg", "none"):
        assert len(p_adjust(p, method)) == len(p)


def test_empty_array_returns_empty():
    result = p_adjust(np.array([]), "holm")
    assert result.size == 0


def test_unknown_method_raises():
    with pytest.raises(ValueError, match="Unknown correction_method"):
        p_adjust(PVALS, "tippett")


def test_single_pvalue():
    result = p_adjust(np.array([0.03]), "holm")
    assert result[0] == pytest.approx(0.03)


def test_by_method():
    result = p_adjust(PVALS, "BY")
    assert len(result) == len(PVALS)
    assert np.all(result <= 1.0)
    assert np.all(result >= 0.0)


def test_hommel_method():
    result = p_adjust(PVALS, "hommel")
    assert len(result) == len(PVALS)
    assert np.all(result <= 1.0)
