from fxhnt.application.honest_gates import risk_parity_weights, book_returns


def test_gate_survives_threshold():
    from fxhnt.application.honest_gates import gate_survives
    strong = {i: (0.01 if i % 2 else -0.002) for i in range(400)}
    assert gate_survives(strong, min_sharpe=1.0) is True
    flat = {i: (0.001 if i % 2 else -0.001) for i in range(400)}
    assert gate_survives(flat, min_sharpe=1.0) is False


def test_loo_marginal_flags_dead_weight():
    from fxhnt.application.honest_gates import loo_marginal
    good = {i: (0.01 if i % 2 else -0.003) for i in range(400)}
    dead = {i: (0.002 if i % 3 else -0.002) for i in range(400)}
    m = loo_marginal({"good": good, "dead": dead})
    assert m["good"] > m["dead"]


def test_beats_concentration_true_when_sleeves_diversify():
    """Two positively-drifting, imperfectly-correlated sleeves (different day-phases: i%2 vs i%3) whose
    risk-parity book Sharpe genuinely exceeds either sleeve alone. NOT anti-correlated cancellation — the
    book still has real (nonzero) vol, it's just lower relative to its return than either sleeve's own."""
    from fxhnt.application.honest_gates import beats_concentration, sharpe_of, book_returns, risk_parity_weights
    a = {i: (0.01 if i % 2 == 0 else -0.003) for i in range(400)}
    b = {i: (0.02 if i % 3 == 0 else -0.002) for i in range(400)}
    rbs = {"a": a, "b": b}
    sa, sb = sharpe_of(a), sharpe_of(b)
    sbook = sharpe_of(book_returns(rbs, risk_parity_weights(rbs)))
    assert sbook > max(sa, sb) > 0   # book genuinely beats both single sleeves
    assert beats_concentration(rbs) is True


def test_beats_concentration_false_when_one_sleeve_dominates():
    """One strong sleeve plus a weak/near-zero-Sharpe sleeve: risk-parity gives the weak sleeve most of the
    weight (it has the lower vol), dragging the book below the strong sleeve's standalone Sharpe."""
    from fxhnt.application.honest_gates import beats_concentration, sharpe_of, book_returns, risk_parity_weights
    strong = {i: (0.01 if i % 2 == 0 else -0.003) for i in range(400)}
    weak = {i: (0.001 if i % 4 in (0, 1) else -0.0011) for i in range(400)}
    rbs = {"strong": strong, "weak": weak}
    sbook = sharpe_of(book_returns(rbs, risk_parity_weights(rbs)))
    assert sbook < sharpe_of(strong)
    assert beats_concentration(rbs) is False


def test_risk_parity_weights_inverse_vol_sum_to_one():
    rbs = {"lowvol": {1: 0.001, 2: -0.001, 3: 0.001},
           "hivol":  {1: 0.10,  2: -0.10,  3: 0.10}}
    w = risk_parity_weights(rbs)
    assert abs(sum(w.values()) - 1.0) < 1e-9
    assert w["lowvol"] > w["hivol"]


def test_book_returns_union_zero_fill():
    rbs = {"a": {1: 0.02, 2: 0.04}, "b": {2: 0.10, 3: 0.20}}   # union of days = {1, 2, 3}
    br = book_returns(rbs, {"a": 0.5, "b": 0.5})
    assert set(br) == {1, 2, 3}
    assert abs(br[1] - (0.5*0.02)) < 1e-9                       # b inactive on day 1 -> contributes 0
    assert abs(br[2] - (0.5*0.04 + 0.5*0.10)) < 1e-9
    assert abs(br[3] - (0.5*0.20)) < 1e-9                       # a inactive on day 3 -> contributes 0


def test_risk_parity_all_degenerate_falls_back_to_equal():
    rbs = {"a": {1: 0.0, 2: 0.0}, "b": {1: 0.0, 2: 0.0}}   # zero vol both -> equal weight
    w = risk_parity_weights(rbs)
    assert abs(w["a"] - 0.5) < 1e-9 and abs(w["b"] - 0.5) < 1e-9


def test_ab_beats_nothing_identical_does_not_beat():
    from fxhnt.application.honest_gates import ab_beats_nothing
    s = {i: (0.01 if i % 2 else -0.002) for i in range(100)}
    assert ab_beats_nothing(s, s) is False        # no change -> not strictly greater
