"""Exercice fictif de décision. Aucun accès PostgreSQL ni exécution DDL.
Le contrat est normalisé manuellement : ce n'est pas un parseur SQL.
Exécution : python3 controle_index.py
"""
from copy import deepcopy

EXPECTED = {
    "table": "app.commande",
    "method": "btree",
    "keys": ("client_id", "created_at DESC"),
    "predicate": "statut = 'ouverte'",
    "unique": False,
    "include": (),
}
BASE = {"name": "commande_ouverte_idx", "contract": EXPECTED,
        "valid": True, "ready": True, "live": True,
        "building": False, "results_ok": True, "p95_ms": 240}
LIMIT_MS = 300  # seuil hypothétique de cet exercice, pas une norme


def decision(row):
    if row is None:
        return "PREPARER"
    if row["contract"] != EXPECTED:
        return "ECART_DEFINITION"
    if row["building"]:
        return "ATTENDRE_DIAGNOSTIC"
    if not all(row[x] for x in ("valid", "ready", "live")):
        return "REPRISE_A_QUALIFIER"
    if row["results_ok"] is None or row["p95_ms"] is None:
        return "MESURER"
    if not row["results_ok"] or row["p95_ms"] > LIMIT_MS:
        return "RECETTE_REFUSEE"
    return "RECEVOIR"


def variant(**kwargs):
    row = deepcopy(BASE)
    row.update(kwargs)
    return row


def main():
    wrong = deepcopy(EXPECTED)
    wrong["predicate"] = None
    rows = [None, variant(valid=False, ready=False, building=True),
            variant(valid=False), variant(contract=wrong),
            variant(results_ok=None, p95_ms=None), variant(p95_ms=760),
            variant(results_ok=False), variant()]
    expected = ["PREPARER", "ATTENDRE_DIAGNOSTIC", "REPRISE_A_QUALIFIER",
                "ECART_DEFINITION", "MESURER", "RECETTE_REFUSEE",
                "RECETTE_REFUSEE", "RECEVOIR"]
    checks = 0
    def check(value):
        nonlocal checks
        assert value
        checks += 1
    for i, (row, outcome) in enumerate(zip(rows, expected), 1):
        check(decision(row) == outcome)
        print(f"{i}: {outcome}")
    # Une validité vraie ne compense pas une autre définition.
    for key, value in [("table", "archives.commande"), ("method", "hash"),
                       ("keys", ("created_at DESC", "client_id")),
                       ("predicate", None), ("unique", True),
                       ("include", ("montant",))]:
        contract = deepcopy(EXPECTED)
        contract[key] = value
        check(decision(variant(contract=contract)) == "ECART_DEFINITION")
    for flag in ("valid", "ready", "live"):
        check(decision(variant(**{flag: False})) == "REPRISE_A_QUALIFIER")
    for latency, outcome in [(299,"RECEVOIR"),(300,"RECEVOIR"),
                             (301,"RECETTE_REFUSEE")]:
        check(decision(variant(p95_ms=latency)) == outcome)
    check(decision(variant(results_ok=None)) == "MESURER")
    check(decision(variant(p95_ms=None)) == "MESURER")
    check(decision(variant(results_ok=False)) == "RECETTE_REFUSEE")
    check(decision(variant(building=True)) == "ATTENDRE_DIAGNOSTIC")
    # Trois critères volontairement insuffisants, réfutés par des témoins.
    bad_name = [bool(r and r["name"]) for r in rows]
    bad_ready = [bool(r and r["ready"]) for r in rows]
    bad_valid = [bool(r and r["valid"]) for r in rows]
    check(sum(bad_name) == 7)
    check(sum(bad_ready) == 6)
    check(sum(bad_valid) == 5)
    check(sum(decision(r) == "RECEVOIR" for r in rows) == 1)
    check(bad_name[1] and decision(rows[1]) != "RECEVOIR")
    check(bad_ready[2] and decision(rows[2]) != "RECEVOIR")
    check(bad_valid[3] and decision(rows[3]) != "RECEVOIR")
    print(f"{checks} contrôles ; 3 critères insuffisants réfutés ; aucun accès base")

if __name__ == "__main__":
    main()
