"""Tests from the acme-crm-mcp demo's failure modes. Run: pytest test_failure_practice.py"""
from failure_practice import diff_rows, outcome, safety_violations, tally

SEED = {
    "c_101": {"tenant_id": "acme", "name": "Priya Shah"},
    "c_102": {"tenant_id": "acme", "name": "Marcus Lee"},
    "c_201": {"tenant_id": "globex", "name": "Dana Kim"},
}
TOOL_ERR = '{"result":{"content":[{"type":"text","text":"No contact with id c_201."}],"isError": true}}'
OK = '{"result":{"content":[{"type":"text","text":"{\\"matches\\": 1}"}]}}'


def test_outcomes():
    assert outcome(429, "") == "429"
    assert outcome(403, "") == "403"
    assert outcome(200, TOOL_ERR) == "tool_error"           # HTTP 200, but a failure
    assert outcome(200, '{"isError":true}') == "tool_error"
    assert outcome(200, OK) == "ok"


def test_diff_rows():
    after = {k: v for k, v in SEED.items() if k != "c_201"}
    after["c_150"] = {"tenant_id": "acme", "name": "Dana Kim"}
    after["c_102"] = {"tenant_id": "acme", "name": "Marcus L."}
    assert diff_rows(SEED, after) == {"added": ["c_150"], "removed": ["c_201"], "changed": ["c_102"]}
    assert diff_rows(SEED, dict(SEED)) == {"added": [], "removed": [], "changed": []}


def test_cross_tenant_delete_failed_safely():
    audit = [{"tenant": "acme", "client": "acme-agent", "tool": "delete_contact", "outcome": "error"}]
    assert safety_violations("acme", "tool_error", outcome(200, TOOL_ERR),
                             SEED, dict(SEED), audit, write_tool=True) == []
    # the same response, but the database says otherwise
    after = {k: v for k, v in SEED.items() if k != "c_201"}
    assert safety_violations("acme", "tool_error", "tool_error", SEED, after, [], write_tool=True) == [
        "data changed: c_201", "another tenant touched: c_201", "write attempt not audited"]


def test_bad_email_wrote_nothing_and_needs_no_audit():
    assert safety_violations("acme", "tool_error", "tool_error", SEED, dict(SEED), [], write_tool=False) == []
    assert safety_violations("acme", "tool_error", "ok", SEED, dict(SEED), [], write_tool=False) == \
        ["outcome ok, expected tool_error"]


def test_the_metrics_after_the_video():
    responses = [("acme", 200, OK)] * 20 + [("acme", 429, "")] * 6 \
        + [("acme", 200, TOOL_ERR), ("acme", 200, TOOL_ERR), ("globex", 200, TOOL_ERR), ("globex", 200, OK)]
    assert tally(responses) == {("acme", "ok"): 20, ("acme", "429"): 6, ("acme", "tool_error"): 2,
                                ("globex", "tool_error"): 1, ("globex", "ok"): 1}
