from conftest import register
from polyform_backend.simulator import Experiment, run_experiment, run_quarantine_experiment


def test_simulator_uses_http_api_for_diversified_population(api,release):
    result=run_experiment("http://testserver",release["id"],Experiment(clients=12,runs_per_client=2,bad=("header_bad",)),transport=api._transport)
    assert result["executions"] == 24
    assert 0 < result["affected_fraction"] < 1
    assert result["failures"] > 0


def test_homogeneous_population_has_one_composition(api,release):
    result=run_experiment("http://testserver",release["id"],Experiment(clients=8,runs_per_client=1,mode="homogeneous",bad=("header_a",)),transport=api._transport)
    dist=result["summary"]["active_distribution"]
    parse=[x for x in dist if x["spec_function"]=="parse_header"]
    assert len(parse)==1 and parse[0]["clients"]==8
    assert result["affected_fraction"] == 1


def test_simulator_attributes_fault_and_quarantine_reduces_failures(api,release):
    cfg=Experiment(clients=12,runs_per_client=4,bad=("header_bad",),seed=11)
    result=run_quarantine_experiment("http://testserver",release["id"],cfg,("header_bad",),transport=api._transport)
    assert result["before"]["failures"] > 0
    assert result["after"]["failures"] == 0
    assert result["failure_rate_drop"] > 0
    events=api.get("/api/v1/telemetry",params={"release_id":release["id"]}).json()
    assert events
    assert all(event["implementation_id"] == "header_bad" for event in events)
    assert all(any(call["implementation_id"] == "header_bad" and call["outcome"] == "error"
                   for call in event["recent_calls"]) for event in events)


def test_simulator_pair_fault_marks_both_members(api,release):
    cfg=Experiment(clients=20,runs_per_client=5,bad_pair=("header_bad","path_b"),seed=19)
    result=run_experiment("http://testserver",release["id"],cfg,transport=api._transport)
    assert result["failures"] > 0
    events=api.get("/api/v1/telemetry",params={"release_id":release["id"]}).json()
    for event in events:
        failed_ids={call["implementation_id"] for call in event["recent_calls"] if call["outcome"]=="error"}
        assert failed_ids == {"header_bad","path_b"}
        assert event["implementation_id"] in failed_ids
