from __future__ import annotations
import pytest
from legal_mcp.services import corroboration as cor

@pytest.mark.parametrize("raw,expected", [
    ({"treatment": "followed"}, "followed"),
    ({"treatment": "OVERRULED"}, "overruled"),     # case-insensitive
    ({"treatment": "bananas"}, "mentioned"),         # unknown -> neutral default
    ({}, "mentioned"),                               # missing -> neutral default
])
def test_coerce_treatment(raw, expected):
    assert cor._coerce_treatment(raw) == expected

def test_treatment_polarity():
    assert cor.is_positive("followed") and cor.is_positive("explained")
    assert cor.is_negative("distinguished") and cor.is_negative("overruled")
    assert not cor.is_positive("mentioned") and not cor.is_negative("mentioned")

def test_match_accepts_above_threshold():
    assert cor.accept_match(("h1", 0.62), floor=0.50) == "h1"

def test_match_rejects_below_threshold():
    assert cor.accept_match(("h1", 0.41), floor=0.50) is None

def test_match_rejects_empty():
    assert cor.accept_match(None, floor=0.50) is None

def _link(src, treatment):
    return {"source_id": src, "treatment": treatment}

def test_aggregate_counts_distinct_positive():
    links = [_link("d1","followed"), _link("d1","explained"), _link("d2","followed")]
    agg = cor.aggregate(links, min_cites=2)
    assert agg["positive_sources"] == 2          # d1 counted once (INV-COR4 independence)
    assert agg["has_negative"] is False
    assert agg["corroborated"] is True

def test_aggregate_negative_blocks():
    links = [_link("d1","followed"), _link("d2","followed"), _link("d3","distinguished")]
    agg = cor.aggregate(links, min_cites=2)
    assert agg["has_negative"] is True
    assert agg["corroborated"] is False          # any negative -> not corroborated (INV-COR2)

def test_aggregate_below_threshold():
    agg = cor.aggregate([_link("d1","followed")], min_cites=2)
    assert agg["corroborated"] is False           # single source insufficient (INV-COR4)


# --- Phase 2: approval decision (INV-COR2/COR4) ---

def test_approval_action_corroborated_approves():
    agg = {"positive_sources": 2, "has_negative": False, "corroborated": True}
    assert cor.approval_action(agg, has_overruled=False) == "approve"

def test_approval_action_overruled_demotes_even_if_corroborated():
    # overruled outranks any positive count (INV-COR2 strong form)
    agg = {"positive_sources": 3, "has_negative": True, "corroborated": False}
    assert cor.approval_action(agg, has_overruled=True) == "demote"

def test_approval_action_single_source_noop():
    agg = {"positive_sources": 1, "has_negative": False, "corroborated": False}
    assert cor.approval_action(agg, has_overruled=False) is None

def test_approval_action_negative_nonoverruled_noop():
    # distinguished blocks approval but does not demote (no overruled)
    agg = {"positive_sources": 2, "has_negative": True, "corroborated": False}
    assert cor.approval_action(agg, has_overruled=False) is None
