#!/usr/bin/env python3
# tests/phase-00-maas-standup/make_fixtures.py
# Emits fix/<scenario>_{subnets,spaces,vlans,ipranges,fabrics}.json for the
# phase-00-maas-standup.sh behavior harness -- D-052/D-053 SIX-PLANE scheme
# (rewritten 2026-07-03: the prior fixtures modeled the retired D-058 target;
# a script migration commit must carry its harness). ASCII + LF.
import json, os

HERE = os.path.dirname(os.path.abspath(__file__))
FIX = os.path.join(HERE, "fix")
os.makedirs(FIX, exist_ok=True)


def sub(cidr, sid, space, vid, fab, mtu=1500, gw=None, managed=True, dns=None):
    return {"cidr": cidr, "id": sid, "space": space,
            "vlan": {"vid": vid, "fabric_id": fab, "mtu": mtu},
            "gateway_ip": gw, "managed": managed, "dns_servers": dns or []}


def vlan(vid, vid_id, fab, space, mtu=1500):
    return {"vid": vid, "id": vid_id, "fabric_id": fab, "space": space, "mtu": mtu}


def dump(scn, subnets, spaces, vlans, ipranges, fabrics):
    for name, obj in (("subnets", subnets), ("spaces", spaces), ("vlans", vlans),
                      ("ipranges", ipranges), ("fabrics", fabrics)):
        with open(os.path.join(FIX, f"{scn}_{name}.json"), "w") as f:
            json.dump(obj, f, indent=2)
            f.write("\n")


def spaces_list(names):
    return [{"name": n, "id": i + 1} for i, n in enumerate(names)]


def fabrics_list(pairs):  # [(name,id)]
    return [{"name": n, "id": i} for n, i in pairs]


SIX = ["provider-public", "metal-admin", "metal-internal",
       "data-tenant", "storage", "replication"]

# ---- FRESH: nothing exists -> full six-plane create plan ----
dump("fresh", [], [], [], [], [])

# ---- DONE: D-052/D-053 fully present + correct -> all SKIP, zero WOULD ----
fabs = fabrics_list([("provider", 1), ("metal", 2), ("data", 3),
                     ("storage", 4), ("replication", 5)])
vl = [
    vlan(0, 10, 1, "provider-public"),
    vlan(0, 20, 2, "metal-admin"), vlan(103, 21, 2, "metal-internal"),
    vlan(0, 30, 3, "data-tenant"),
    vlan(0, 40, 4, "storage"),
    vlan(0, 50, 5, "replication"),
]
subs = [
    sub("10.12.4.0/22", 1, "provider-public", 0, 1, gw="10.12.4.1"),
    sub("10.12.8.0/22", 2, "metal-admin", 0, 2, gw="10.12.8.1"),
    sub("10.12.12.0/22", 3, "metal-internal", 103, 2),
    sub("10.12.16.0/22", 4, "data-tenant", 0, 3),
    sub("10.12.32.0/22", 5, "storage", 0, 4),
    sub("10.12.36.0/22", 6, "replication", 0, 5),
]
ipr = [{"start_ip": s, "end_ip": e, "type": "reserved"} for s, e in [
    ("10.12.4.2", "10.12.4.100"), ("10.12.4.101", "10.12.4.110"),
    ("10.12.5.0", "10.12.7.254"),
    ("10.12.8.2", "10.12.8.100"), ("10.12.8.101", "10.12.8.110"),
    ("10.12.12.2", "10.12.12.100"),
]]
dump("done", subs, spaces_list(SIX), vl, ipr, fabs)

# ---- DRIFT: one target CIDR bound to the WRONG plane -> DRIFT + refuse ----
subs_d = [dict(s) for s in subs]
for s in subs_d:
    if s["cidr"] == "10.12.16.0/22":
        s["space"] = "storage"          # wrong plane on data-tenant's CIDR
dump("drift", subs_d, spaces_list(SIX), vl, ipr, fabs)

# ---- WRONGVID: metal-internal subnet exists but on VID 99 -> drift(vid) ----
subs_v = [dict(s) for s in subs]
for s in subs_v:
    if s["cidr"] == "10.12.12.0/22":
        s["vlan"] = {"vid": 99, "fabric_id": 2, "mtu": 1500}
dump("wrongvid", subs_v, spaces_list(SIX), vl, ipr, fabs)
