#!/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. 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]


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

# ---- DONE: D-058 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(104, 11, 1, "provider-vip"),
    vlan(0, 20, 2, "metal-admin"),     vlan(103, 21, 2, "metal-internal", mtu=9000),
    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, "provider-vip", 104, 1, gw="10.12.8.1"),  # dns mirrors metal-internal (which is unset) -> left unset
    sub("10.12.12.0/22", 3, "metal-admin", 0, 2, gw="10.12.12.1"),
    sub("10.12.16.0/22", 4, "metal-internal", 103, 2, mtu=9000),
    sub("10.12.20.0/22", 5, "data-tenant", 0, 3),
    sub("10.12.32.0/22", 6, "storage", 0, 4),
    sub("10.12.36.0/22", 7, "replication", 0, 5),
]
spc = spaces_list(["provider-public", "provider-vip", "metal-admin", "metal-internal",
                   "data-tenant", "storage", "replication"])
ipr = [{"type": "reserved", "start_ip": lo, "end_ip": hi, "subnet": {"id": sid}}
       for lo, hi, sid in [("10.12.5.0", "10.12.7.254", 1),      # FIP pool (provider-public)
                           ("10.12.4.101", "10.12.4.110", 1),    # provider-public mgmt
                           ("10.12.8.2", "10.12.8.100", 2),      # provider-vip API VIP
                           ("10.12.12.2", "10.12.12.100", 3),    # metal-admin API VIP
                           ("10.12.12.101", "10.12.12.110", 3),  # metal-admin mgmt
                           ("10.12.16.2", "10.12.16.100", 4)]]   # metal-internal API VIP
dump("done", subs, spc, vl, ipr, fabs)

# ---- D-052 CURRENT (old live scheme): the three migrating planes drift ----
fabs_c = fabrics_list([("1_provider", 1), ("2_metal", 2), ("4_data", 3),
                       ("8_storage", 4), ("9_replication", 5)])
vl_c = [
    vlan(0, 10, 1, "provider-public"),
    vlan(0, 20, 2, "metal-admin"), vlan(103, 21, 2, "metal-internal", mtu=9000),
    vlan(0, 30, 3, "data-tenant"), vlan(0, 40, 4, "storage"), vlan(0, 50, 5, "replication"),
]
subs_c = [
    sub("10.12.4.0/22", 1, "provider-public", 0, 1, gw="10.12.4.1"),   # correct under D-058 -> SKIP
    sub("10.12.8.0/22", 2, "metal-admin", 0, 2, gw="10.12.8.1"),        # D-058 wants provider-vip -> DRIFT
    sub("10.12.12.0/22", 3, "metal-internal", 103, 2, mtu=9000),        # D-058 wants metal-admin -> DRIFT
    sub("10.12.16.0/22", 4, "data-tenant", 0, 3),                       # D-058 wants metal-internal -> DRIFT
    sub("10.12.32.0/22", 6, "storage", 0, 4),                           # correct -> SKIP
    sub("10.12.36.0/22", 7, "replication", 0, 5),                       # correct -> SKIP
]
spc_c = spaces_list(["provider-public", "metal-admin", "metal-internal",
                     "data-tenant", "storage", "replication"])
dump("d052", subs_c, spc_c, vl_c, [], fabs_c)

# ---- WRONG-VID: provider-vip subnet present at .8 but on VID 99 ----
vl_w = [v for v in vl if v["vid"] != 104] + [vlan(99, 11, 1, "provider-vip")]
subs_w = [s for s in subs if s["cidr"] != "10.12.8.0/22"] + \
         [sub("10.12.8.0/22", 2, "provider-vip", 99, 1, gw="10.12.8.1")]
dump("wrongvid", subs_w, spc, vl_w, ipr, fabs)

print("fixtures written to", FIX)
