#!/usr/bin/env python3
# fake jq for behavior-testing: implements ONLY the programs phase-02-vault-preflight.sh uses.
# Metrics are computed by an independent Python mirror of the jq logic, so the bash
# decision/exit logic runs for real against algorithmically-correct values.
import sys, json
argv = sys.argv[1:]
args = {}; prog = None; i = 0
while i < len(argv):
    a = argv[i]
    if a in ("-r", "--raw-output", "-e", "--exit-status"): i += 1; continue
    if a == "--arg": args[argv[i+1]] = argv[i+2]; i += 3; continue
    if prog is None and not a.startswith("-"): prog = a; i += 1; continue
    i += 1
try:
    data = json.load(sys.stdin)
except Exception:
    sys.exit(0)

def walk(x, out):
    if isinstance(x, dict):
        if "workload-status" in x: out.append(x)
        for v in x.values(): walk(v, out)
    elif isinstance(x, list):
        for v in x: walk(v, out)

def all_units(root):
    out = []
    for app in (root.get("applications") or {}).values():
        walk(app.get("units") or {}, out)
    return out

def app_units(root, a):
    app = (root.get("applications") or {}).get(a) or {}
    return list((app.get("units") or {}).values())

def ws(u): return (u.get("workload-status") or {})
def ags(u): return (u.get("juju-status") or {})

if prog and ".models[]?.name" in prog:
    for m in (data.get("models") or []):
        if m.get("name") is not None: print(m["name"])
    sys.exit(0)

if prog and "mach_total=" in prog:
    machines = data.get("machines") or {}
    db = app_units(data, args.get("dbapp"))
    vt = app_units(data, args.get("vaultapp"))
    u = all_units(data)
    c = lambda lst, p: sum(1 for x in lst if p(x))
    kv = {
        "mach_total": len(machines),
        "mach_started": c(list(machines.values()), lambda m: (m.get("juju-status") or {}).get("current") == "started"),
        "db_units": len(db),
        "db_online": c(db, lambda x: "ONLINE" in (ws(x).get("message") or "")),
        "db_rw": c(db, lambda x: "Mode: R/W" in (ws(x).get("message") or "")),
        "db_active": c(db, lambda x: ws(x).get("current") == "active"),
        "v_units": len(vt),
        "v_fresh": c(vt, lambda x: ws(x).get("current") == "blocked" and "needs to be initialized" in (ws(x).get("message") or "").lower()),
        "we": c(u, lambda x: ws(x).get("current") == "error"),
        "ae": c(u, lambda x: ags(x).get("current") == "error"),
        "c_blocked": c(u, lambda x: ws(x).get("current") == "blocked"),
        "c_waiting": c(u, lambda x: ws(x).get("current") == "waiting"),
        "c_active": c(u, lambda x: ws(x).get("current") == "active"),
        "c_unknown": c(u, lambda x: ws(x).get("current") == "unknown"),
        "c_total": len(u),
    }
    print("\n".join(f"{k}={v}" for k, v in kv.items()))
    sys.exit(0)

# cosmetic display programs -> no output (does not affect the verdict)
sys.exit(0)
