#!/usr/bin/env python3
"""Synthetic fallback selection; Python 3.9+, stdlib only, no discovery.

All edges, possible completions, mappings and cost units are author inputs.
Edges run dependency -> consumer. Explicit checks survive Python optimization.
Exit zero means the demonstration oracle held, not that candidate tests passed.
"""
import itertools
import json

OBSERVED_EDGES = {("serializer", "api")}
TRUE_EDGES = OBSERVED_EDGES | {("serializer", "invoice")}
CHANGED = {"serializer"}
TARGETS = {"serializer_test": "serializer", "api_test": "api",
           "invoice_test": "invoice", "analytics_test": "analytics",
           "health_test": "health"}
COST_UNITS = {"serializer_test": 1, "api_test": 2, "invoice_test": 5,
              "analytics_test": 8, "health_test": 1}
BILLING_UNKNOWN = {("serializer", "invoice"), ("api", "invoice")}
CROSS_UNKNOWN = BILLING_UNKNOWN | {("invoice", "analytics")}
UNBOUNDED_UNKNOWN = CROSS_UNKNOWN | {("serializer", "health")}


class TestFailure(Exception):
    pass


def check(condition, message):
    if not condition:
        raise TestFailure(message)


def expect(condition, message):
    if not condition:
        raise RuntimeError("demonstration expectation failed: " + message)


def reachable(edges):
    seen = set(CHANGED)
    while True:
        expanded = seen | {consumer for dep, consumer in edges if dep in seen}
        if expanded == seen:
            return seen
        seen = expanded


def select(edges, mapping):
    affected = reachable(edges)
    return sorted(name for name, target in mapping.items() if target in affected)


def completions(possible_edges):
    """All subsets are plausible, NOT equally probable or discovered."""
    ordered = sorted(possible_edges)
    return [OBSERVED_EDGES | {edge for edge, present in zip(ordered, bits) if present}
            for bits in itertools.product((False, True), repeat=len(ordered))]


def fallback(possible_edges, mapping):
    graphs = completions(possible_edges)
    affected = set().union(*(reachable(graph) for graph in graphs))
    selected = sorted(name for name, target in mapping.items() if target in affected)
    gaps = sorted(affected - set(mapping.values()))
    return {"possible_edges": sorted(map(list, possible_edges)),
            "plausible_graph_count": len(graphs), "affected_nodes": sorted(affected),
            "selected": selected, "selected_count": len(selected),
            "illustrative_cost_units": sum(COST_UNITS[name] for name in selected),
            "unmapped_affected_nodes": gaps,
            "mapping_status": "INCOMPLETE" if gaps else "ACCOUNTED_FOR"}


def serialize(version):
    return {"amount": "10.00" if version.startswith("baseline") else 10.0}


def serializer_test(version):
    check("amount" in serialize(version), "amount field missing")


def api_test(version):
    check(float(serialize(version)["amount"]) == 10.0, "numeric value changed")


def invoice_test(version):
    amount = serialize(version)["amount"]
    check(isinstance(amount, str), "invoice requires amount as a string")
    check(amount == "10.00", "invoice requires two decimal places")


def analytics_test(version):
    # In the cross-domain installation analytics reads invoice's serialized amount.
    amount = serialize(version)["amount"] if version.endswith("_cross") else "10.00"
    check(isinstance(amount, str), "analytics requires invoice amount as a string")


def health_test(version):
    check({"status": "ok"}["status"] == "ok", "health status changed")


TESTS = {name: globals()[name] for name in TARGETS}


def run(version, inventory):
    results = {}
    for name in inventory:
        try:
            TESTS[name](version)
        except TestFailure as error:
            results[name] = {"status": "FAIL", "reason": str(error)}
        else:
            results[name] = {"status": "PASS"}
    return {"version": version, "selected": inventory, "results": results}


def main():
    mapping_gap = {name: target for name, target in TARGETS.items() if target != "invoice"}
    plans = {"billing_bounded": fallback(BILLING_UNKNOWN, TARGETS),
             "cross_domain": fallback(CROSS_UNKNOWN, TARGETS),
             "no_exclusion_boundary": fallback(UNBOUNDED_UNKNOWN, TARGETS),
             "billing_missing_mapping": fallback(BILLING_UNKNOWN, mapping_gap)}
    full = sorted(TARGETS)
    runs = {"baseline_full": run("baseline", full),
            "baseline_cross_full": run("baseline_cross", full),
            "candidate_observed_targeted": run("candidate", select(OBSERVED_EDGES, TARGETS)),
            "candidate_full": run("candidate", full),
            "candidate_repaired_targeted": run("candidate", select(TRUE_EDGES, TARGETS)),
            "candidate_billing_fallback": run("candidate", plans["billing_bounded"]["selected"]),
            "cross_candidate_billing_only": run("candidate_cross", plans["billing_bounded"]["selected"]),
            "cross_candidate_fallback": run("candidate_cross", plans["cross_domain"]["selected"]),
            "candidate_missing_mapping_fallback": run("candidate", plans["billing_missing_mapping"]["selected"]),
            "candidate_full_mapped_inventory": run("candidate", sorted(mapping_gap))}
    for label in ("baseline_full", "baseline_cross_full", "candidate_observed_targeted",
                  "candidate_missing_mapping_fallback", "candidate_full_mapped_inventory"):
        expect(all(r["status"] == "PASS" for r in runs[label]["results"].values()), label)
    expect(runs["candidate_observed_targeted"]["selected"] == ["api_test", "serializer_test"], "observed selection")
    for label in ("candidate_full", "candidate_repaired_targeted", "candidate_billing_fallback",
                  "cross_candidate_billing_only", "cross_candidate_fallback"):
        expect(runs[label]["results"]["invoice_test"]["status"] == "FAIL", label + " invoice failure")
    expect(runs["cross_candidate_fallback"]["results"]["analytics_test"]["status"] == "FAIL", "cross-domain failure")
    expect("analytics_test" not in runs["cross_candidate_billing_only"]["selected"], "billing-only omits analytics")
    expected = {"billing_bounded": (4, 3, 8), "cross_domain": (8, 4, 16),
                "no_exclusion_boundary": (16, 5, 17), "billing_missing_mapping": (4, 2, 3)}
    for label, triple in expected.items():
        plan = plans[label]
        expect((plan["plausible_graph_count"], plan["selected_count"], plan["illustrative_cost_units"]) == triple, label + " counts/cost")
        union = sorted(set().union(*(set(select(graph, TARGETS if label != "billing_missing_mapping" else mapping_gap))
                                    for graph in completions(set(map(tuple, plan["possible_edges"]))))))
        expect(plan["selected"] == union, label + " union selection")
    expect(plans["billing_missing_mapping"]["unmapped_affected_nodes"] == ["invoice"], "mapping gap retained")
    expect(plans["billing_missing_mapping"]["mapping_status"] == "INCOMPLETE", "mapping is not a pass")
    expect("health_test" not in plans["cross_domain"]["selected"], "cross boundary excludes health")
    expect(plans["no_exclusion_boundary"]["selected"] == full, "unbounded fallback is full")
    expect(TRUE_EDGES in completions(BILLING_UNKNOWN), "bounded true graph included")
    cross_true = TRUE_EDGES | {("invoice", "analytics")}
    expect(cross_true in completions(CROSS_UNKNOWN), "cross true graph included")
    expect(cross_true not in completions(BILLING_UNKNOWN), "billing assumption invalid in cross world")
    print(json.dumps({"edge_direction": "dependency -> consumer", "changed": sorted(CHANGED),
                      "true_edges_author_supplied": sorted(map(list, TRUE_EDGES)),
                      "cross_true_edges_author_supplied": sorted(map(list, cross_true)),
                      "observed_edges": sorted(map(list, OBSERVED_EDGES)),
                      "test_targets": TARGETS, "illustrative_cost_units": COST_UNITS,
                      "plans": plans, "runs": runs, "demonstration_checks": "PASS"}, indent=2, sort_keys=True))


if __name__ == "__main__":
    main()
