"""Deterministic idempotent simulation seed profiles."""

from __future__ import annotations

import json
import uuid
from dataclasses import dataclass

import asyncpg  # type: ignore[import-untyped]
from asyncpg import Connection

from app.security.auth import hash_secret
from app.simulation.ceph_defaults import default_ceph_flags

NAMESPACE = uuid.UUID("c9040a72-b391-4a7e-9864-3ae46291a531")
CLUSTER_ID = uuid.UUID("dc760c47-d8d7-57e6-9404-f0c6f2395d8f")


def default_node_ops_for_seed(
    node_name: str, *, node_index: int = 0, node_count: int = 1, osds_per_node: int = 1
) -> dict[str, object]:
    """Full durable node ops written to nodes.metadata at seed time."""

    suffix = (stable_id(f"node-ip:{node_name}").int % 200) + 10
    disk_count = max(2, osds_per_node + 1)

    def _disk_path(disk_index: int) -> str:
        if disk_index < 26:
            return f"/dev/sd{chr(ord('a') + disk_index)}"
        # Beyond sdz keep unique, stable SCSI-style ids.
        return f"/dev/disk/by-id/scsi-SIM{disk_index:04d}"

    disk_list = [
        {
            "devpath": _disk_path(disk_index),
            "size": (1_000_000_000_000 if disk_index == 0 else 2_000_000_000_000),
            "model": "SIM-DISK-01" if disk_index == 0 else f"SIM-OSD-{disk_index:02d}",
            "serial": f"SIM{disk_index:04d}",
            "gpt": 1 if disk_index == 0 else 0,
        }
        for disk_index in range(disk_count)
    ]
    return {
        "network": [
            {
                "iface": "vmbr0",
                "type": "bridge",
                "active": 1,
                "method": "static",
                "address": f"10.0.0.{suffix}/24",
            },
            {
                "iface": "vmbr1",
                "type": "bridge",
                "active": 1,
                "method": "static",
                "address": f"10.10.0.{suffix}/24",
            },
            {"iface": "eno1", "type": "eth", "active": 1, "method": "manual"},
        ],
        "disks": {
            "list": disk_list,
            "directory": [],
            "lvm": [],
            "lvmthin": [],
            "zfs": [],
            "smart": {
                item["devpath"]: {
                    "health": "PASSED",
                    "type": "scsi",
                    "model": item["model"],
                    "serial": item["serial"],
                }
                for item in disk_list
            },
        },
        "services": {
            "pveproxy": {"state": "running", "enabled": 1, "desc": "PVE API Proxy Server"},
            "pvedaemon": {"state": "running", "enabled": 1, "desc": "PVE API Daemon"},
            "pvestatd": {"state": "running", "enabled": 1, "desc": "PVE Status Daemon"},
            "corosync": {"state": "running", "enabled": 1, "desc": "Corosync Cluster Engine"},
            "pve-ha-crm": {"state": "running", "enabled": 1, "desc": "PVE HA CRM Daemon"},
            "pve-ha-lrm": {"state": "running", "enabled": 1, "desc": "PVE HA LRM Daemon"},
            "pvescheduler": {"state": "running", "enabled": 1, "desc": "Proxmox VE scheduler"},
            "ceph-mon": {"state": "running", "enabled": 1, "desc": "Ceph Monitor"},
            "ceph-mgr": {"state": "running", "enabled": 1, "desc": "Ceph Manager"},
            "ceph-osd": {"state": "running", "enabled": 1, "desc": "Ceph Object Storage Daemon"},
        },
        "apt": {
            "packages": [
                {
                    "Package": "pve-manager",
                    "Version": "9.2.3",
                    "OldVersion": "9.2.2",
                    "CurrentState": "Installed",
                    "Arch": "amd64",
                    "Origin": "Proxmox",
                },
                {
                    "Package": "libpve-common-perl",
                    "Version": "9.0.3",
                    "CurrentState": "Installed",
                    "Arch": "amd64",
                    "Origin": "Proxmox",
                },
                {
                    "Package": "pve-kernel-6.8",
                    "Version": "6.8.12-1",
                    "CurrentState": "Installed",
                    "Arch": "amd64",
                    "Origin": "Proxmox",
                },
                {
                    "Package": "ceph-common",
                    "Version": "18.2.2",
                    "CurrentState": "Installed",
                    "Arch": "amd64",
                    "Origin": "Proxmox",
                },
            ],
            "repositories": {
                "digest": "seedapt",
                "errors": [],
                "infos": [],
                "standard-repos": [
                    {
                        "handle": "enterprise",
                        "name": "Proxmox VE Enterprise Repository",
                        "status": 0,
                    },
                    {
                        "handle": "no-subscription",
                        "name": "Proxmox VE No-Subscription Repository",
                        "status": 1,
                    },
                ],
                "files": [
                    {
                        "path": "/etc/apt/sources.list.d/pve-enterprise.list",
                        "file-type": "list",
                        "digest": "seedapt-file0",
                        "repositories": [
                            {
                                "Types": "deb",
                                "URIs": "http://download.proxmox.com/debian/pve",
                                "Suites": "bookworm",
                                "Components": "pve-no-subscription",
                                "Enabled": 1,
                            }
                        ],
                    }
                ],
            },
            "update": {"status": "stopped", "exitstatus": "OK"},
            "changelogs": {
                "pve-manager": "pve-manager (9.2.3) bookworm\n\n  * simulator seed\n",
            },
        },
        "hardware": {
            "pci": [
                {
                    "id": "0000:00:1f.2",
                    "vendor_name": "Intel Corporation",
                    "device_name": "SATA Controller",
                    "iommugroup": 0,
                },
                {
                    "id": "0000:01:00.0",
                    "vendor_name": "NVIDIA Corporation",
                    "device_name": "GP102 [GeForce GTX 1080 Ti]",
                    "iommugroup": 1,
                    "mdev": 1,
                },
            ],
            "usb": [
                {
                    "busnum": 1,
                    "devnum": 1,
                    "level": 0,
                    "port": "1",
                    "prodid": "0002",
                    "vendid": "1d6b",
                },
                {
                    "busnum": 2,
                    "devnum": 2,
                    "level": 1,
                    "port": "2",
                    "prodid": "5591",
                    "vendid": "0781",
                },
            ],
            "mdev": {
                "0000:01:00.0": [
                    {"type": "nvidia-11", "available": 4, "description": "GRID profile"},
                ]
            },
        },
        "scan": {
            "cifs": [{"server": "files.local", "share": "backups"}],
            "iscsi": [{"portal": "10.0.0.50:3260", "target": "iqn.2024-01.local:storage"}],
            "lvm": [{"vg": "pve", "size": 500_000_000_000, "free": 100_000_000_000}],
            "lvmthin": [{"lv": "data", "vg": "pve", "lv_size": 400_000_000_000}],
            "nfs": [{"server": "nfs.local", "path": "/export/pve", "options": "vers=4"}],
            "pbs": [{"server": "pbs.local", "datastore": "store1"}],
            "zfs": [{"pool": "rpool", "name": "rpool/data", "size": 800_000_000_000}],
        },
        "subscription": {
            "status": "notfound",
            "message": "There is no subscription key",
            "serverid": "SIMULATOR",
            "sockets": 1,
            "productname": "Proxmox VE",
            "url": "https://www.proxmox.com/en/proxmox-virtual-environment/pricing",
        },
        "dns": {"search": "local", "dns1": "1.1.1.1", "dns2": "8.8.8.8", "dns3": ""},
        "time": {"timezone": "UTC", "time": 1_720_000_000, "localtime": 1_720_000_000},
        "config": {
            "description": "Simulator node",
            "startall-onboot-delay": 0,
            "wakeonlan": "",
        },
        "certificates": {
            "custom": None,
            "acme": {"account": "letsencrypt", "domains": [], "certificate": None},
            "info": [
                {
                    "filename": "pve-ssl.pem",
                    "fingerprint": _seed_fingerprint(node_name),
                    "issuer": f"CN={node_name}.proxmox.local",
                    "subject": f"CN={node_name}.proxmox.local",
                    "notbefore": 1_700_000_000,
                    "notafter": 2_000_000_000,
                    "pem": (
                        "-----BEGIN CERTIFICATE-----\n"
                        "SIMULATOR-SEED-CERT\n"
                        "-----END CERTIFICATE-----\n"
                    ),
                    "san": [f"{node_name}.proxmox.local", f"IP:10.0.0.{suffix}"],
                    "public-key-type": "rsa",
                    "public-key-bits": 4096,
                }
            ],
        },
        "ceph": {
            "mds": {},
            "mgr": {
                node_name: {
                    "name": node_name,
                    "state": "active" if node_index == 0 else "standby",
                    "addr": f"{node_name}.local:6800",
                }
            },
            "mon": {
                node_name: {
                    "name": node_name,
                    "rank": node_index,
                    "addr": f"{node_name}.local:6789",
                }
            },
            "log": [{"t": 1_700_000_000, "n": 0, "line": "ceph simulator ready"}],
        },
        "aplinfo": [
            {
                "package": "alpine-3-standard",
                "section": "system",
                "type": "lxc",
                "version": "3.20",
            }
        ],
        "oci_tags": {"library/alpine": [{"tag": "latest"}, {"tag": "3.20"}]},
        "capabilities": {
            "cpu": [
                {"name": "host", "vendor": "QEMU", "custom": 0},
                {"name": "x86-64-v2-AES", "vendor": "QEMU", "custom": 0},
                {"name": "kvm64", "vendor": "QEMU", "custom": 0},
            ],
            "cpu_flags": [
                {"name": "aes", "introduces": "Westmere"},
                {"name": "avx", "introduces": "SandyBridge"},
                {"name": "avx2", "introduces": "Haswell"},
            ],
            "machines": [
                {"id": "pc-i440fx-9.0", "type": "i440fx", "version": "9.0"},
                {"id": "pc-q35-9.0", "type": "q35", "version": "9.0"},
            ],
            "migration": {"network": "", "type": "secure", "enabled": 1},
        },
        "hosts": {
            "data": f"127.0.0.1 localhost\n10.0.0.{suffix} {node_name}\n",
            "digest": "seedhosts",
        },
        "journal": [
            f"0: {node_name} systemd[1]: Started pveproxy.service.",
            f"1: {node_name} systemd[1]: Started pvedaemon.service.",
            f"2: {node_name} kernel: Booting simulator node {node_name}.",
        ],
        "syslog": [
            {"n": 0, "t": f"{node_name} kernel: simulator syslog ready"},
            {"n": 1, "t": f"{node_name} pvestatd[1]: status update ok"},
        ],
        "netstat": [
            {
                "in": 1_000_000,
                "out": 900_000,
                "vnet": "vmbr0",
                "hwaddr": "bc:24:11:00:00:01",
            },
            {
                "in": 500_000,
                "out": 450_000,
                "vnet": "vmbr1",
                "hwaddr": "bc:24:11:00:00:02",
            },
        ],
        "report": f"==== Proxmox node report for {node_name} ====\nuptime: seeded\n",
        "rrd": {"filename": f"/var/lib/rrdcached/db/pve-node-{node_name}.rrd"},
        "rrddata": [
            {"time": 1_720_000_000 - 120, "cpu": 0.05, "memused": 1_000_000_000},
            {"time": 1_720_000_000 - 60, "cpu": 0.07, "memused": 1_100_000_000},
            {"time": 1_720_000_000, "cpu": 0.04, "memused": 1_050_000_000},
        ],
        "vzdump": {
            "defaults": {
                "all": 0,
                "bwlimit": 0,
                "compress": "zstd",
                "dumpdir": "backup",
                "mode": "snapshot",
                "remove": 0,
                "storage": "local",
                "mailto": "",
                "notes-template": "{{guestname}}",
            },
            "extractconfig": {
                "local:backup/vzdump-qemu-100.vma.zst": (
                    "# vzdump config for local:backup/vzdump-qemu-100.vma.zst\n"
                    "name: demo\nmemory: 2048\n"
                ),
            },
        },
        "status": {
            "uptime": 86_400 + suffix,
            "cpu": 0.05 + (suffix % 10) * 0.01,
            "mem": 4_000_000_000 + suffix * 10_000_000,
            "maxmem": 32_000_000_000,
            "maxcpu": 16,
            "memory": {
                "used": 4_000_000_000 + suffix * 10_000_000,
                "total": 32_000_000_000,
                "free": 28_000_000_000 - suffix * 10_000_000,
                "available": 28_000_000_000 - suffix * 10_000_000,
            },
            "rootfs": {
                "used": 12 * 1024**3,
                "total": 100 * 1024**3,
                "avail": 88 * 1024**3,
                "free": 88 * 1024**3,
            },
            "swap": {"used": 0, "total": 8 * 1024**3, "free": 8 * 1024**3},
            "cpuinfo": {
                "cpus": 16,
                "cores": 8,
                "sockets": 2,
                "model": "QEMU Virtual CPU version 2.5+",
                "flags": "fpu vme de pse tsc msr pae mce cx8",
            },
            "boot-info": {"mode": "efi", "secureboot": 0},
            "current-kernel": {
                "sysname": "Linux",
                "release": "6.8.12-1-pve",
                "version": "#1 SMP PREEMPT_DYNAMIC PMX 6.8.12-1",
                "machine": "x86_64",
            },
            "loadavg": ["0.10", "0.20", "0.30"],
            "kversion": "6.8.12-1-pve",
            "pveversion": "pve-manager/9.2.3",
            "ssl_fingerprint": _seed_fingerprint(node_name),
        },
        "ip": f"10.32.1.{suffix}",
        "cluster_status": {
            "ip": f"10.32.1.{suffix}",
            "level": "",
            "type": "node",
            "quorate": 1,
        },
    }


def enrich_guest_state(
    state: dict[str, object],
    *,
    kind: str,
    vmid: str,
    slim: bool = False,
) -> dict[str, object]:
    """Ensure qemu/lxc resources carry durable agent/rrd/migrate catalogs.

    ``slim=True`` (large profiles) keeps wire config keys without heavy agent/rrd.
    """

    enriched = dict(state)
    name = str(enriched.get("name") or f"{kind}-{vmid}")
    suffix = stable_id(f"guest-runtime:{kind}:{vmid}").int % 200
    if slim:
        if kind == "qemu":
            enriched.setdefault("scsi0", f"local-lvm:vm-{vmid}-disk-0,size=32G")
            enriched.setdefault("scsihw", "virtio-scsi-pci")
            enriched.setdefault("ostype", "l26")
            enriched.setdefault("boot", "order=scsi0")
            enriched.setdefault("net0", f"virtio=02:00:00:00:{suffix:02x}:01,bridge=vmbr0")
            enriched.setdefault("memory", enriched.get("memory") or 2048)
            enriched.setdefault("cores", enriched.get("cores") or 2)
            enriched.setdefault("agent", "1")
            enriched.setdefault("maxdisk", 32 * 1024**3)
        else:
            enriched.setdefault("rootfs", f"local-lvm:vm-{vmid}-disk-0,size=8G")
            enriched.setdefault("ostype", "alpine")
            enriched.setdefault("unprivileged", 1)
            enriched.setdefault("swap", 512)
            enriched.setdefault(
                "net0",
                f"name=eth0,bridge=vmbr0,hwaddr=02:00:00:00:{suffix:02x}:11,ip=dhcp",
            )
            enriched.setdefault("memory", enriched.get("memory") or 512)
            enriched.setdefault("cores", enriched.get("cores") or 1)
            enriched.setdefault("hostname", name)
            enriched.setdefault("maxdisk", 8 * 1024**3)
        enriched.setdefault("status", enriched.get("status") or "stopped")
        enriched.setdefault("name", name)
        # Lightweight runtime counters so list/status dumps stay PVE-shaped without
        # storing full agent/rrd catalogs for thousand-guest profiles.
        running = str(enriched.get("status")) in {"running", "paused"}
        enriched.setdefault("cpu", 0.12 if running else 0.0)
        enriched.setdefault("disk", (suffix + 1) * 1024**2 if running else 0)
        enriched.setdefault("diskread", suffix * 10_000 if running else 0)
        enriched.setdefault("diskwrite", suffix * 4_000 if running else 0)
        enriched.setdefault("netin", suffix * 8_000 if running else 0)
        enriched.setdefault("netout", suffix * 3_000 if running else 0)
        enriched.setdefault("uptime", 3_600 + suffix if running else 0)
        enriched.setdefault("pid", 12_000 + suffix if running else 0)
        return enriched

    agent_enabled = enriched.get("agent")
    if isinstance(agent_enabled, bool) and not agent_enabled:
        agent: dict[str, object] = {"enabled": False, "files": {}, "results": {}}
    else:
        existing_agent = enriched.get("agent")
        agent = dict(existing_agent) if isinstance(existing_agent, dict) else {}
        files = agent.get("files")
        if not isinstance(files, dict):
            files = {}
        files.setdefault("/etc/hostname", f"{name}\n")
        agent["files"] = files
        results = agent.get("results")
        if not isinstance(results, dict):
            results = {}
        results.setdefault(
            "info",
            {
                "version": "9.2.0-simulator",
                "supported_commands": [
                    {"name": "guest-ping", "enabled": True, "success-response": True},
                    {"name": "guest-info", "enabled": True, "success-response": True},
                    {"name": "guest-get-osinfo", "enabled": True, "success-response": True},
                ],
            },
        )
        results.setdefault(
            "get-osinfo",
            {
                "name": str(enriched.get("ostype") or "l26"),
                "pretty-name": f"Simulator guest {name}",
                "version": "1.0",
                "machine": "x86_64",
            },
        )
        results.setdefault("get-host-name", {"host-name": name})
        results.setdefault(
            "network-get-interfaces",
            [
                {
                    "name": "eth0",
                    "hardware-address": f"02:00:00:00:{suffix:02x}:01",
                    "ip-addresses": [
                        {
                            "ip-address": f"192.0.2.{(suffix % 200) + 10}",
                            "ip-address-type": "ipv4",
                            "prefix": 24,
                        }
                    ],
                }
            ],
        )
        results.setdefault("ping", {})
        results.setdefault("get-users", [{"user": "root", "login-time": 0}])
        results.setdefault(
            "get-fsinfo",
            [{"name": "/", "type": "ext4", "total-bytes": 32 * 1024**3}],
        )
        results.setdefault("get-memory-block-info", {"size": 1024**3})
        results.setdefault("get-memory-blocks", [{"start": 0, "size": 1024**3}])
        results.setdefault("get-timezone", {"zone": "UTC", "offset": 0})
        results.setdefault("get-vcpus", [{"online": True, "can-offline": False}])
        results.setdefault("fsfreeze-status", "thawed")
        results.setdefault("fstrim", {"paths": [{"path": "/", "trimmed": 0}]})
        agent["results"] = results
        agent["enabled"] = True
    enriched["agent"] = agent
    if "rrd" not in enriched or not isinstance(enriched.get("rrd"), dict):
        prefix = "pve-vm" if kind == "qemu" else "pve-ct"
        enriched["rrd"] = {"filename": f"{prefix}-{vmid}.rrd"}
    if "rrddata" not in enriched or not isinstance(enriched.get("rrddata"), list):
        memory = enriched.get("memory", 256)
        mem_mb = int(memory) if isinstance(memory, int | float | str) else 256
        mem = mem_mb * 1024 * 1024
        enriched["rrddata"] = [
            {"time": 1_720_000_000, "cpu": 0.05, "mem": mem, "netin": 0, "netout": 0},
            {
                "time": 1_720_000_060,
                "cpu": 0.08,
                "mem": mem + 4_000_000,
                "netin": 100,
                "netout": 80,
            },
        ]
    if "migrate_preconditions" not in enriched or not isinstance(
        enriched.get("migrate_preconditions"), dict
    ):
        enriched["migrate_preconditions"] = {"local_disks": [], "local_resources": []}
    if kind == "lxc" and (
        "interfaces" not in enriched or not isinstance(enriched.get("interfaces"), list)
    ):
        enriched["interfaces"] = [
            {
                "name": "eth0",
                "hwaddr": f"02:00:00:00:{suffix:02x}:11",
                "inet": f"192.0.2.{(suffix % 200) + 20}/24",
            }
        ]
    if "cloudinit_dump" not in enriched:
        enriched["cloudinit_dump"] = f"#cloud-config\nhostname: {name}\nmanage_etc_hosts: true\n"
    # Disk keys live in guest config so resize/move handlers work after seed.
    if kind == "qemu":
        enriched.setdefault("scsi0", f"local-lvm:vm-{vmid}-disk-0,size=32G")
        enriched.setdefault("scsihw", "virtio-scsi-pci")
        enriched.setdefault("ostype", "l26")
        enriched.setdefault("boot", "order=scsi0")
        enriched.setdefault("net0", f"virtio=02:00:00:00:{suffix:02x}:01,bridge=vmbr0")
        enriched.setdefault("memory", enriched.get("memory") or 2048)
        enriched.setdefault("cores", enriched.get("cores") or 2)
        enriched.setdefault("maxdisk", 32 * 1024**3)
    elif kind == "lxc":
        enriched.setdefault("rootfs", f"local-lvm:vm-{vmid}-disk-0,size=8G")
        enriched.setdefault("ostype", "alpine")
        enriched.setdefault("unprivileged", 1)
        enriched.setdefault("swap", 512)
        enriched.setdefault(
            "net0",
            f"name=eth0,bridge=vmbr0,hwaddr=02:00:00:00:{suffix:02x}:11,ip=dhcp",
        )
        enriched.setdefault("memory", enriched.get("memory") or 512)
        enriched.setdefault("cores", enriched.get("cores") or 1)
        enriched.setdefault("hostname", name)
        enriched.setdefault("maxdisk", 8 * 1024**3)
    running = str(enriched.get("status") or "stopped") in {"running", "paused"}
    enriched.setdefault("cpu", 0.12 if running else 0.0)
    enriched.setdefault("disk", (suffix + 1) * 1024**2 if running else 0)
    enriched.setdefault("diskread", suffix * 10_000 if running else 0)
    enriched.setdefault("diskwrite", suffix * 4_000 if running else 0)
    enriched.setdefault("netin", suffix * 8_000 if running else 0)
    enriched.setdefault("netout", suffix * 3_000 if running else 0)
    enriched.setdefault("uptime", 3_600 + suffix if running else 0)
    enriched.setdefault("pid", 12_000 + suffix if running else 0)
    return enriched


def enrich_storage_state(state: dict[str, object], *, storage_id: str) -> dict[str, object]:
    enriched = dict(state)
    if "total_bytes" not in enriched and "capacity_bytes" not in enriched:
        enriched["total_bytes"] = 100 * 1024**3
    if "used_bytes" not in enriched:
        total_hint = enriched.get("total_bytes", enriched.get("capacity_bytes", 100 * 1024**3))
        total_i = int(total_hint) if isinstance(total_hint, int | float | str) else 100 * 1024**3
        enriched["used_bytes"] = max(total_i // 10, 1)
    total_raw = enriched.get("total_bytes", enriched.get("capacity_bytes", 100))
    total = int(total_raw) if isinstance(total_raw, int | float | str) else 100
    used_raw = enriched.get("used_bytes", max(total // 10, 1))
    used = int(used_raw) if isinstance(used_raw, int | float | str) else max(total // 10, 1)
    enriched.setdefault("disk", used)
    enriched.setdefault("maxdisk", total)
    if "plugintype" not in enriched:
        if "lvm" in storage_id:
            enriched["plugintype"] = "lvmthin"
        elif storage_id.startswith("ceph"):
            enriched["plugintype"] = "rbd"
        elif storage_id.startswith("nfs"):
            enriched["plugintype"] = "nfs"
        else:
            enriched["plugintype"] = "dir"
    if "content" not in enriched:
        enriched["content"] = ["images"]
    if "rrd" not in enriched or not isinstance(enriched.get("rrd"), dict):
        enriched["rrd"] = {"filename": f"pve-storage-{storage_id}.rrd"}
    if "rrddata" not in enriched or not isinstance(enriched.get("rrddata"), list):
        enriched["rrddata"] = [
            {"time": 1_720_000_000, "used": used, "total": total},
            {"time": 1_720_000_060, "used": min(used + total // 50, total), "total": total},
        ]
    if "file_restore" not in enriched or not isinstance(enriched.get("file_restore"), dict):
        enriched["file_restore"] = {
            "/": [{"filepath": "/etc", "type": "d", "text": "etc"}],
            "/etc": [
                {"filepath": "/etc/hostname", "type": "f", "text": "hostname"},
                {"filepath": "/etc/hosts", "type": "f", "text": "hosts"},
            ],
        }
    if "import_metadata" not in enriched or not isinstance(enriched.get("import_metadata"), dict):
        enriched["import_metadata"] = {
            "type": "qemu",
            "disks": {"scsi0": f"{storage_id}:0/vm-import.raw"},
            "net0": "virtio,bridge=vmbr0",
        }
    if "identity" not in enriched or not isinstance(enriched.get("identity"), dict):
        enriched["identity"] = {
            "fingerprint": f"fp-{storage_id}",
            "type": str(enriched.get("storage_type") or enriched.get("plugintype") or "dir"),
        }
    return enriched


@dataclass(frozen=True, slots=True)
class SeedNode:
    id: uuid.UUID
    name: str
    status: str


@dataclass(frozen=True, slots=True)
class SeedResource:
    id: uuid.UUID
    node_id: uuid.UUID
    kind: str
    external_id: str
    state: dict[str, object]


@dataclass(frozen=True, slots=True)
class SeedTask:
    id: uuid.UUID
    upid: str
    task_type: str
    payload: dict[str, object]


@dataclass(frozen=True, slots=True)
class SeedProfile:
    name: str
    nodes: tuple[SeedNode, ...]
    resources: tuple[SeedResource, ...]
    tasks: tuple[SeedTask, ...] = ()

    def logical_state(self) -> dict[str, object]:
        nodes = [{"name": node.name, "status": node.status} for node in self.nodes]
        names = {node.id: node.name for node in self.nodes}
        resources = [
            {
                "kind": resource.kind,
                "external_id": resource.external_id,
                "node": names[resource.node_id],
                "state": resource.state,
            }
            for resource in self.resources
        ]
        tasks = [
            {"upid": task.upid, "task_type": task.task_type, "status": "success"}
            for task in self.tasks
        ]
        return {"profile": self.name, "nodes": nodes, "resources": resources, "tasks": tasks}


def stable_id(name: str) -> uuid.UUID:
    return uuid.uuid5(NAMESPACE, name)


def _empty_firewall_scope(*, options: dict[str, object] | None = None) -> dict[str, object]:
    return {
        "options": dict(
            options
            or {
                "enable": 1,
                "policy_in": "DROP",
                "policy_out": "ACCEPT",
                "log_level_in": "nolog",
                "log_level_out": "nolog",
            }
        ),
        "rules": [],
        "aliases": {},
        "ipset": {},
        "groups": {},
        "log": [],
    }


def _seed_fingerprint(node_name: str) -> str:
    digest = stable_id(f"pve-fp:{node_name}").hex
    # SHA-256 fingerprint wire form: 32 colon-separated hex bytes.
    padded = (digest * 4)[:64]
    return ":".join(padded[index : index + 2].upper() for index in range(0, 64, 2))


def _seed_cluster_config(profile_name: str, node_names: list[str]) -> dict[str, object]:
    clustername = f"pve-{profile_name}"
    added_nodes: dict[str, dict[str, object]] = {}
    for index, node_name in enumerate(node_names, start=1):
        suffix = (stable_id(f"node-ip:{node_name}").int % 200) + 10
        addr = f"10.0.0.{suffix}"
        added_nodes[node_name] = {
            "node": node_name,
            "nodeid": index,
            "ring0_addr": addr,
            "pve_addr": addr,
            "pve_fp": _seed_fingerprint(node_name),
            "quorum_votes": 1,
        }
    nodelist_lines = ["nodelist {"]
    for node_name, entry in added_nodes.items():
        nodelist_lines.extend(
            [
                "  node {",
                f"    name: {node_name}",
                f"    nodeid: {entry['nodeid']}",
                f"    quorum_votes: {entry['quorum_votes']}",
                f"    ring0_addr: {entry['ring0_addr']}",
                "  }",
            ]
        )
    nodelist_lines.append("}")
    corosync_conf = "\n".join(
        [
            "totem {",
            "  version: 2",
            f"  cluster_name: {clustername}",
            "  secauth: on",
            "}",
            *nodelist_lines,
            "quorum {",
            "  provider: corosync_votequorum",
            "}",
            "",
        ]
    )
    return {
        "clustername": clustername,
        "votes": 1,
        "links": {},
        "join_info": {},
        "totem": {
            "version": 2,
            "secauth": "on",
            "cluster_name": clustername,
        },
        "qdevice": {"status": "disabled"},
        "apiversion": 1,
        "corosync_authkey": stable_id(f"corosync-authkey:{clustername}").hex,
        "corosync_conf": corosync_conf,
        "config_digest": stable_id(f"corosync-digest:{clustername}").hex,
        "added_nodes": added_nodes,
    }


def _replication_seed_jobs(
    profile_name: str,
    *,
    qemu_guests: list[tuple[str, str]],
    node_names: list[str],
    primary: str,
    secondary: str,
    multi_node: bool,
) -> list[dict[str, object]]:
    """Proportional sample replication jobs for multi-node cluster profiles."""

    if not multi_node or not qemu_guests:
        return []
    job_count = max(int(_size_spec(profile_name).get("replication", 1)), 0)
    if job_count <= 0:
        return []
    targets = [name for name in node_names if name != primary] or [secondary]
    jobs: list[dict[str, object]] = []
    for index, (source, guest) in enumerate(qemu_guests[:job_count]):
        target = targets[index % len(targets)]
        if target == source and len(targets) > 1:
            target = targets[(index + 1) % len(targets)]
        jobs.append(
            {
                "id": f"{guest}-0",
                "guest": int(guest),
                "jobnum": 0,
                "target": target,
                "type": "local",
                "schedule": "*/15",
                "rate": 100,
                "comment": f"Replicate VM/CT {guest} to {target}",
                "disable": 0,
                "source": source,
            }
        )
    return jobs


def cluster_domain_metadata(profile: SeedProfile) -> dict[str, object]:
    """Durable cluster metadata domains so list endpoints are non-empty after seed."""

    node_names = [node.name for node in profile.nodes]
    primary = node_names[0] if node_names else "pve01"
    # Single-node profiles must not invent ghost peers (replication/SDN).
    secondary = node_names[1] if len(node_names) > 1 else primary
    multi_node = len(node_names) > 1
    node_by_id = {node.id: node.name for node in profile.nodes}

    qemu_guests: list[tuple[str, str]] = []
    lxc_guests: list[tuple[str, str]] = []
    for resource in profile.resources:
        node_name = node_by_id.get(resource.node_id)
        if node_name is None:
            continue
        if resource.kind == "qemu":
            qemu_guests.append((node_name, resource.external_id))
        elif resource.kind == "lxc":
            lxc_guests.append((node_name, resource.external_id))

    scale = _size_spec(profile.name)
    guest_cap = int(scale.get("fw_guest_cap", 10_000))
    qemu_guests = qemu_guests[:guest_cap]
    lxc_guests = lxc_guests[:guest_cap]
    osd_count = sum(1 for resource in profile.resources if resource.kind == "ceph-osd")
    guest_total = sum(1 for resource in profile.resources if resource.kind in {"qemu", "lxc"})

    cluster_fw = _empty_firewall_scope(
        options={
            "enable": 1,
            "policy_in": "DROP",
            "policy_out": "ACCEPT",
            "log_level_in": "info",
            "log_level_out": "nolog",
        }
    )
    cluster_fw["aliases"] = {
        "mgmt-net": {
            "name": "mgmt-net",
            "cidr": "10.0.0.0/24",
            "comment": "Management network",
        },
        "monitoring": {
            "name": "monitoring",
            "cidr": "10.20.0.0/24",
            "comment": "Prometheus / Grafana",
        },
    }
    cluster_fw["ipset"] = {
        "blocked-scanners": {
            "name": "blocked-scanners",
            "comment": "Known scanners",
            "entries": {
                "203.0.113.0/24": {
                    "cidr": "203.0.113.0/24",
                    "comment": "RFC5737 TEST-NET-3",
                    "nomatch": 0,
                }
            },
        }
    }
    cluster_fw["groups"] = {
        "web-tier": {
            "comment": "HTTP/HTTPS services",
            "rules": [
                {
                    "type": "in",
                    "action": "ACCEPT",
                    "proto": "tcp",
                    "dport": "443",
                    "comment": "HTTPS",
                    "enable": 1,
                    "pos": 0,
                }
            ],
        }
    }
    cluster_fw["rules"] = [
        {
            "type": "in",
            "action": "ACCEPT",
            "source": "+mgmt-net",
            "macro": "SSH",
            "comment": "SSH from mgmt",
            "enable": 1,
            "pos": 0,
        },
        {
            "type": "in",
            "action": "ACCEPT",
            "source": "+monitoring",
            "dport": "9100",
            "proto": "tcp",
            "comment": "Node exporter",
            "enable": 1,
            "pos": 1,
        },
        {
            "type": "in",
            "action": "DROP",
            "source": "+blocked-scanners",
            "comment": "Drop scanners",
            "enable": 1,
            "pos": 2,
        },
    ]
    cluster_fw["log"] = [
        {
            "n": 0,
            "t": 1720000000,
            "msg": "DROP IN 198.51.100.10 → 10.0.0.10:22 proto=tcp",
        }
    ]

    scopes: dict[str, object] = {"cluster": cluster_fw}
    for node_name in node_names:
        scope = _empty_firewall_scope()
        scope["rules"] = [
            {
                "type": "in",
                "action": "ACCEPT",
                "iface": "vmbr0",
                "comment": f"Allow bridge traffic on {node_name}",
                "enable": 1,
                "pos": 0,
            }
        ]
        scope["aliases"] = {
            f"{node_name}-mgmt": {
                "name": f"{node_name}-mgmt",
                "cidr": "10.0.0.0/24",
                "comment": f"{node_name} management",
            }
        }
        scope["ipset"] = {
            f"{node_name}-trusted": {
                "name": f"{node_name}-trusted",
                "comment": "Trusted clients",
                "entries": {
                    "10.0.0.0/8": {
                        "cidr": "10.0.0.0/8",
                        "comment": "RFC1918",
                        "nomatch": 0,
                    }
                },
            }
        }
        scope["log"] = [
            {
                "n": 0,
                "t": 1720000100,
                "msg": f"ACCEPT IN vmbr0 on {node_name}",
            }
        ]
        scopes[f"node:{node_name}"] = scope

    for node_name, vmid in qemu_guests:
        scope = _empty_firewall_scope()
        scope["rules"] = [
            {
                "type": "in",
                "action": "ACCEPT",
                "proto": "tcp",
                "dport": "443",
                "comment": f"HTTPS on VM {vmid}",
                "enable": 1,
                "pos": 0,
            }
        ]
        host = (stable_id(f"fw-vip:{vmid}").int % 250) + 1
        scope["aliases"] = {
            f"vm{vmid}-vip": {
                "name": f"vm{vmid}-vip",
                "cidr": f"10.10.{host}.10/32",
                "comment": f"VIP for VM {vmid}",
            }
        }
        scopes[f"qemu:{node_name}:{vmid}"] = scope

    for node_name, vmid in lxc_guests:
        scope = _empty_firewall_scope()
        scope["rules"] = [
            {
                "type": "in",
                "action": "ACCEPT",
                "proto": "tcp",
                "dport": "22",
                "comment": f"SSH on CT {vmid}",
                "enable": 1,
                "pos": 0,
            }
        ]
        scopes[f"lxc:{node_name}:{vmid}"] = scope

    ha_nodes = ",".join(node_names) if node_names else primary
    return {
        "firewall": {"scopes": scopes},
        "options": {
            "keyboard": "en-us",
            "email_from": "pve@example.local",
            "http_proxy": "",
            "description": f"Proxmox API simulator ({profile.name})",
            "mac_prefix": "BC:24:11",
        },
        "quorate": 1,
        "ha": {
            "armed": True,
            "status_current": {"quorate": 1, "mode": "active"},
            "manager_status": {"manager_status": "active", "quorum": "OK"},
        },
        "backup_jobs": {
            (f"backup-{index}" if index else "backup-daily"): {
                "id": f"backup-{index}" if index else "backup-daily",
                "schedule": f"{index * 2} 2 * * *",
                "storage": "local" if index % 2 == 0 else "ceph",
                "enabled": 1,
                "all": 0,
                "vmid": ",".join(
                    guest
                    for _, guest in (
                        qemu_guests[index * 3 : index * 3 + 3] or qemu_guests[:1] or [("x", "100")]
                    )
                ),
                "mode": "snapshot",
                "compress": "zstd",
                "comment": f"Seeded backup job #{index}",
            }
            for index in range(max(int(scale.get("backup_jobs", 1)), 0))
            if qemu_guests or profile.name == "lab"
        },
        "ha_groups": {
            name: {
                "nodes": ha_nodes,
                "nofailback": 1 if index else 0,
                "restricted": 0,
                "comment": f"HA group {name}",
            }
            for index, name in enumerate(
                (
                    "primary",
                    "critical-services",
                    "batch",
                    "gpu",
                    "edge",
                    "dr",
                )[: max(int(scale.get("ha_groups", 2)), 1)]
            )
        },
        "ha_rules": [
            {"rule": "node-fencing", "type": "node", "action": "restart"},
            {"rule": "service-ha", "type": "resource", "action": "failover"},
            *(
                [{"rule": "affinity-primary", "type": "resource", "action": "prefer-primary"}]
                if int(scale.get("ha_groups", 2)) > 2
                else []
            ),
        ],
        "sdn": {
            "zones": {
                "public": {
                    "zone": "public",
                    "type": "simple",
                    "bridge": "vmbr0",
                    "bridges": [{"iface": "vmbr0", "active": 1}],
                    "vrf": "vrf-public",
                    "table": 100,
                    "mtu": 1500,
                    "nodes": ",".join(node_names),
                    "digest": "sdnzonepublic",
                    "pending": False,
                    "state": "available",
                    "comment": "Public zone",
                },
                "internal": {
                    "zone": "internal",
                    "type": "vlan",
                    "bridge": "vmbr1",
                    "bridges": [{"iface": "vmbr1", "active": 1}],
                    "vrf": "vrf-internal",
                    "table": 101,
                    "vlan-protocol": "802.1q",
                    "nodes": ",".join(node_names),
                    "digest": "sdnzoneinternal",
                    "pending": False,
                    "state": "available",
                    "comment": "Internal VLAN zone",
                },
            },
            "vnets": {
                "vnet0": {
                    "vnet": "vnet0",
                    "type": "vnet",
                    "zone": "public",
                    "alias": "Public VNet",
                    "mac-vrf": "macvrf-vnet0",
                    "tag": 0,
                    "digest": "sdnvnet0",
                    "pending": False,
                    "state": "available",
                    "subnets": {
                        "10.0.0.0/24": {
                            "subnet": "10.0.0.0/24",
                            "gateway": "10.0.0.1",
                            "snat": 0,
                        }
                    },
                    "ips": [],
                    "firewall": {
                        "options": {"enable": 1},
                        "rules": [
                            {
                                "type": "in",
                                "action": "ACCEPT",
                                "proto": "tcp",
                                "dport": "443",
                                "enable": 1,
                                "pos": 0,
                            }
                        ],
                    },
                },
                "vnet1": {
                    "vnet": "vnet1",
                    "type": "vnet",
                    "zone": "internal",
                    "alias": "Internal VNet",
                    "mac-vrf": "macvrf-vnet1",
                    "tag": 100,
                    "digest": "sdnvnet1",
                    "pending": False,
                    "state": "available",
                    "subnets": {
                        "10.10.0.0/24": {
                            "subnet": "10.10.0.0/24",
                            "gateway": "10.10.0.1",
                            "snat": 1,
                        }
                    },
                    "ips": [],
                    "firewall": {"options": {"enable": 0}, "rules": []},
                },
            },
            "controllers": {
                "evpn1": {
                    "controller": "evpn1",
                    "type": "evpn",
                    "asn": 65000,
                    "peers": secondary if multi_node else primary,
                    "comment": "EVPN controller",
                }
            },
            "dns": {
                "powerdns": {
                    "dns": "powerdns",
                    "type": "powerdns",
                    "url": "http://dns.example.local:8081",
                    "key": "seed-dns-key",
                    "ttl": 300,
                }
            },
            "ipams": {
                "pve": {"ipam": "pve", "type": "pve", "comment": "Built-in IPAM"},
                "netbox": {
                    "ipam": "netbox",
                    "type": "netbox",
                    "url": "https://netbox.example.local",
                    "token": "seed-netbox-token",
                },
            },
            "fabrics": {
                "fabric0": {
                    "id": "fabric0",
                    "protocol": "ospf",
                    "ip-prefix": "10.99.0.0/24",
                    "comment": "Underlay fabric",
                    "routes": [{"dst": "10.99.0.0/24", "protocol": "ospf"}],
                }
            },
            "fabric_nodes": {
                "fabric0": {
                    node_name: {
                        "node": node_name,
                        "interfaces": ["eno1"],
                        "state": "up",
                    }
                    for node_name in node_names[:3] or [primary]
                }
            },
            "prefix_lists": {
                "pl-default": {
                    "name": "pl-default",
                    "entries": {"10": {"seq": "10", "action": "permit", "prefix": "10.0.0.0/8"}},
                }
            },
            "route_maps": {
                "rm-default": {
                    "name": "rm-default",
                    "entries": {"10": {"seq": "10", "action": "permit", "match": "pl-default"}},
                }
            },
            "lock": None,
            "pending": False,
            "running_version": 1,
        },
        "firewall_macros": [
            {"macro": "SSH", "descr": "Secure Shell"},
            {"macro": "HTTPS", "descr": "Secure web server"},
            {"macro": "HTTP", "descr": "Web server"},
        ],
        "notifications": {
            "matcher_fields": [
                {"name": "type", "type": "string"},
                {"name": "hostname", "type": "string"},
                {"name": "job-id", "type": "string"},
                {"name": "severity", "type": "string"},
            ],
            "matcher_field_values": [
                {"field": "type", "value": "fencing"},
                {"field": "type", "value": "package-updates"},
                {"field": "type", "value": "replication"},
                {"field": "type", "value": "system-mail"},
            ],
            "endpoints": {
                "gotify": {
                    "ops-gotify": {
                        "name": "ops-gotify",
                        "server": "https://gotify.example.local",
                        "token": "seed-gotify-token",
                        "comment": "Ops Gotify",
                        "disable": 0,
                    }
                },
                "sendmail": {
                    "local-mail": {
                        "name": "local-mail",
                        "mailto": "ops@example.local",
                        "from-address": "pve@example.local",
                        "comment": "Local sendmail",
                        "disable": 0,
                    }
                },
                "smtp": {
                    "alerts": {
                        "name": "alerts",
                        "server": "smtp.example.local",
                        "port": 587,
                        "mode": "starttls",
                        "from-address": "pve@example.local",
                        "mailto": "ops@example.local",
                        "comment": "Ops SMTP",
                        "disable": 0,
                    }
                },
                "webhook": {
                    "pager": {
                        "name": "pager",
                        "url": "https://hooks.example.local/pve",
                        "method": "post",
                        "comment": "Webhook pager",
                        "disable": 0,
                    }
                },
            },
            "matchers": {
                "backup-failures": {
                    "name": "backup-failures",
                    "match-field": ["type=package-updates"],
                    "target": ["alerts", "ops-gotify"],
                    "mode": "always",
                    "comment": "Route package/update noise",
                    "disable": 0,
                }
            },
            "tests": [],
        },
        "acme": {
            "accounts": {
                "letsencrypt": {
                    "name": "letsencrypt",
                    "contact": ["mailto:admin@example.local"],
                    "directory": "https://acme-v02.api.letsencrypt.org/directory",
                    "location": "https://acme.example.local/acct/letsencrypt",
                    "tos_url": "https://acme-v02.api.letsencrypt.org/directory/tos",
                }
            },
            "plugins": {
                "cf-dns": {
                    "id": "cf-dns",
                    "type": "dns",
                    "api": "CF",
                    "data": {"CF_Token": "seed-cf-token"},
                    "validation-delay": 30,
                    "digest": "seedacmeplugin00000000000000000000000001",
                }
            },
            "directories": [
                {
                    "name": "Let's Encrypt V2",
                    "url": "https://acme-v02.api.letsencrypt.org/directory",
                },
                {
                    "name": "Let's Encrypt V2 Staging",
                    "url": "https://acme-staging-v02.api.letsencrypt.org/directory",
                },
            ],
            "challenge_schema": [
                {
                    "id": "dns",
                    "name": "DNS plugin",
                    "type": "dns",
                    "fields": [{"name": "api", "type": "string"}],
                }
            ],
            "meta": {
                "https://acme-v02.api.letsencrypt.org/directory": {
                    "termsOfService": "https://acme-v02.api.letsencrypt.org/directory/tos",
                    "caaIdentities": ["letsencrypt.org"],
                },
                "https://acme-staging-v02.api.letsencrypt.org/directory": {
                    "termsOfService": (
                        "https://acme-staging-v02.api.letsencrypt.org/directory/tos"
                    ),
                    "caaIdentities": ["letsencrypt.org"],
                },
            },
        },
        "mapping": {
            "pci": {
                "gpu0": {
                    "id": "gpu0",
                    "map": [f"{primary};0000:01:00.0;"],
                    "description": "Passthrough GPU",
                }
            },
            "usb": {
                "backup-key": {
                    "id": "backup-key",
                    "map": [f"{primary};2-2;"],
                    "description": "USB backup key",
                }
            },
            "dir": {
                "shared-data": {
                    "id": "shared-data",
                    "map": [f"{primary};/mnt/shared;"],
                    "description": "Shared directory mapping",
                }
            },
        },
        "replication": _replication_seed_jobs(
            profile.name,
            qemu_guests=qemu_guests,
            node_names=node_names,
            primary=primary,
            secondary=secondary,
            multi_node=multi_node,
        ),
        "metrics": {
            "export_data": (
                "# HELP pve_up Node is up\n"
                + "".join(f'pve_up{{node="{name}"}} 1\n' for name in node_names)
            ),
            "servers": {
                "influx": {
                    "id": "influx",
                    "type": "influxdb",
                    "server": "influx.example.local",
                    "port": 8086,
                    "organization": "lab",
                    "bucket": "pve",
                    "enable": 1,
                    "comment": "InfluxDB metrics sink",
                }
            },
        },
        "jobs": {
            "realm_sync": {
                "ldap-sync": {
                    "id": "ldap-sync",
                    "realm": "pam",
                    "schedule": "0 3 * * *",
                    "enable": 1,
                    "comment": "Nightly realm sync",
                }
            },
            "schedule_analyze_results": [
                {"timestamp": 1_720_000_900, "utc": True},
                {"timestamp": 1_720_001_800, "utc": True},
                {"timestamp": 1_720_002_700, "utc": True},
                {"timestamp": 1_720_003_600, "utc": True},
            ],
        },
        "qemu_cpu_models": {
            "lab-cpu": {
                "name": "lab-cpu",
                "vendor": "GenuineIntel",
                "flags": "+aes",
                "comment": "Custom lab CPU model",
            }
        },
        "qemu_cpu_flags": [
            {"name": "aes", "introduces": "Westmere"},
            {"name": "avx", "introduces": "SandyBridge"},
            {"name": "avx2", "introduces": "Haswell"},
        ],
        "ceph": {
            "initialized": True,
            "running": True,
            "version": {"str": "18.2.2", "parts": [18, 2, 2]},
            "config": {
                "network": "10.10.10.0/24",
                "cluster-network": "10.10.10.0/24",
                "size": 3,
                "min_size": 2,
                "pg_bits": 7,
                "fsid": "pve-simulator-fsid",
            },
            "cfg_db": [
                {"section": "global", "name": "auth_client_required", "value": "cephx"},
                {"section": "global", "name": "fsid", "value": "pve-simulator-fsid"},
            ],
            "cfg_raw": "[global]\nfsid = pve-simulator-fsid\nauth_client_required = cephx\n",
            "cfg_values": {},
            "pools": {
                name: {
                    "pool_id": index,
                    "pool_name": name,
                    "size": 3,
                    "min_size": 2,
                    "pg_num": max(32, min((osd_count or 1) * 32, 8192)),
                    "application": "rbd" if name == "rbd" else "cephfs",
                    "application_metadata": {"rbd": {}} if name == "rbd" else {"cephfs": {}},
                    "crush_rule": 0,
                    "crush_rule_name": "replicated_rule",
                    "bytes_used": max(guest_total, 1) * (8 + index * 4) * 1024**3,
                    "percent_used": min(5.0 + guest_total / 50.0, 75.0),
                    "healthy": True,
                }
                for index, name in enumerate(
                    ("rbd", "cephfs_data", "cephfs_metadata")[
                        : (1 if osd_count < 10 else 2 if osd_count < 100 else 3)
                    ]
                )
            },
            "fs": {},
            "rules": [{"name": "replicated_rule", "id": 0}],
            "crush": "".join(
                f"device {index} osd.{index} class hdd\n" for index in range(max(osd_count, 1))
            ),
            "cmd_safety": {"safe": 1},
            "health": {"status": "HEALTH_OK"},
            "flags": default_ceph_flags(),
        },
        "cluster_config": _seed_cluster_config(profile.name, node_names),
    }


def _seed_resource_state(resource: SeedResource, *, slim: bool = False) -> dict[str, object]:
    if resource.kind in {"qemu", "lxc"}:
        return enrich_guest_state(
            dict(resource.state), kind=resource.kind, vmid=resource.external_id, slim=slim
        )
    if resource.kind == "storage":
        return enrich_storage_state(dict(resource.state), storage_id=resource.external_id)
    if resource.kind == "ceph-osd":
        state = dict(resource.state)
        state.setdefault("uuid", f"osd-uuid-{resource.external_id}")
        state.setdefault("dev", f"/dev/{resource.external_id.replace('.', '')}")
        state.setdefault("device_class", "hdd")
        return state
    return dict(resource.state)


def _string_list(state: dict[str, object], key: str) -> tuple[str, ...]:
    value = state.get(key, [])
    if not isinstance(value, list) or not all(isinstance(item, str) for item in value):
        raise ValueError(f"seed state {key} must be a string list")
    return tuple(value)


def _node(name: str, status: str = "online") -> SeedNode:
    return SeedNode(stable_id(f"node:{name}"), name, status)


def _resource(
    node: SeedNode, kind: str, external_id: str, state: dict[str, object]
) -> SeedResource:
    return SeedResource(stable_id(f"{kind}:{external_id}"), node.id, kind, external_id, state)


def _completed_task(
    index: int,
    task_type: str,
    resource_id: str,
    *,
    node: str = "pve01",
) -> SeedTask:
    pid = index & 0xFFFFFFFF
    start = (0x65000000 + index) & 0xFFFFFFFF
    return SeedTask(
        stable_id(f"task:{index}:{task_type}:{resource_id}:{node}"),
        (f"UPID:{node}:{pid:08X}:{pid:08X}:{start:08X}:{task_type}:{resource_id}:root@pam:"),
        task_type,
        {"resource_id": resource_id, "node": node, "seeded": True},
    )


def _storage_resource(
    node: SeedNode,
    storage_id: str,
    *,
    content: list[str],
    total_bytes: int,
    used_bytes: int,
    plugintype: str,
    shared: bool = False,
) -> SeedResource:
    return _resource(
        node,
        "storage",
        storage_id,
        {
            "content": content,
            "status": "available",
            "shared": shared,
            "total_bytes": total_bytes,
            "used_bytes": used_bytes,
            "plugintype": plugintype,
            "disk": used_bytes,
            "maxdisk": total_bytes,
        },
    )


def _ceph_osd_resource(node: SeedNode, osd_id: int) -> SeedResource:
    return _resource(
        node,
        "ceph-osd",
        f"osd.{osd_id}",
        {
            "osd_id": osd_id,
            "status": "up",
            "in": 1,
            "weight": 1.0,
            "device_class": "hdd",
            "dev": f"/dev/disk/by-id/ceph-osd-{osd_id:04d}",
        },
    )


def _distribute_count(total: int, buckets: int) -> list[int]:
    """Spread ``total`` items across ``buckets`` as evenly as possible."""

    if buckets <= 0 or total <= 0:
        return [0] * max(buckets, 0)
    base, rem = divmod(total, buckets)
    return [base + (1 if index < rem else 0) for index in range(buckets)]


def _cluster_infra(
    nodes: tuple[SeedNode, ...],
    *,
    include_ceph: bool = True,
    osd_count: int = 0,
    osds_per_node: int | None = None,
    ha_sids: tuple[str, ...] = (),
    pool_id: str | None = None,
    pool_members: tuple[str, ...] = (),
    guest_count: int = 50,
) -> list[SeedResource]:
    """Shared storages / Ceph OSDs / HA / pool rows for multi-node profiles.

    ``storages.storage_id`` is unique cluster-wide, so ``local`` / ``local-lvm`` /
    ``ceph`` are seeded once (standard PVE names). Node storage list and
    ``/cluster/resources`` expand them onto every node.
    """

    resources: list[SeedResource] = []
    if not nodes:
        return resources
    primary = nodes[0]
    if osds_per_node is not None and osd_count <= 0:
        osd_count = max(osds_per_node, 0) * len(nodes)
    # Scale capacity with guest + OSD count so dumps stay realistic.
    local_total = max(200 * 1024**3, guest_count * 4 * 1024**3)
    local_used = local_total // 5
    lvm_total = max(800 * 1024**3, guest_count * 40 * 1024**3)
    lvm_used = lvm_total // 6
    ceph_total = max(
        max(osd_count, 1) * 2 * 1024**4,
        len(nodes) * 2 * 1024**4,
        guest_count * 64 * 1024**3,
    )
    ceph_used = max(
        max(osd_count, 1) * 200 * 1024**3,
        len(nodes) * 200 * 1024**3,
        guest_count * 8 * 1024**3,
    )
    resources.append(
        _storage_resource(
            primary,
            "local",
            content=["iso", "backup", "vztmpl", "images"],
            total_bytes=local_total,
            used_bytes=local_used,
            plugintype="dir",
        )
    )
    resources.append(
        _storage_resource(
            primary,
            "local-lvm",
            content=["images", "rootdir"],
            total_bytes=lvm_total,
            used_bytes=lvm_used,
            plugintype="lvmthin",
        )
    )
    if include_ceph:
        resources.append(
            _storage_resource(
                primary,
                "ceph",
                content=["images", "rootdir"],
                total_bytes=ceph_total,
                used_bytes=ceph_used,
                plugintype="rbd",
                shared=True,
            )
        )
        per_node = _distribute_count(max(osd_count, 0), len(nodes))
        osd_id = 0
        for node, node_osds in zip(nodes, per_node, strict=True):
            for _ in range(node_osds):
                resources.append(_ceph_osd_resource(node, osd_id))
                osd_id += 1
    for sid in ha_sids:
        guest_kind, _, _guest_id = sid.partition(":")
        resources.append(
            _resource(
                primary,
                "ha",
                sid,
                {"state": "started", "group": "primary", "type": guest_kind or "vm"},
            )
        )
    if pool_id:
        resources.append(
            _resource(
                primary,
                "pool",
                pool_id,
                {"members": list(pool_members), "comment": f"Pool {pool_id}"},
            )
        )
    return resources


def _seed_tasks_for_guests(
    nodes: tuple[SeedNode, ...],
    guest_ids: list[tuple[str, str]],
    *,
    limit: int = 20,
) -> tuple[SeedTask, ...]:
    """Create completed tasks bound to the guest's real node name."""

    tasks: list[SeedTask] = []
    for index, (node_name, vmid) in enumerate(guest_ids[:limit], start=1):
        tasks.append(_completed_task(index, "qmstart", vmid, node=node_name))
    return tuple(tasks)


# UI / ops cluster sizes (hosts x total guests). Infra scales with the size.
_CLUSTER_SIZE_SPECS: dict[str, dict[str, int]] = {
    "lab": {
        "nodes": 1,
        "guests": 3,
        "osds": 3,
        "ha": 1,
        "tasks": 2,
        "pool_members": 2,
        "replication": 0,
        "backups": 2,
        "snapshots": 2,
        "backup_jobs": 1,
        "ha_groups": 2,
        "fw_guest_cap": 10_000,
    },
    "small": {
        "nodes": 3,
        "guests": 50,
        "osds": 10,
        "ha": 3,
        "tasks": 12,
        "pool_members": 12,
        "replication": 2,
        "backups": 10,
        "snapshots": 12,
        "backup_jobs": 2,
        "ha_groups": 2,
        "fw_guest_cap": 10_000,
    },
    "large": {
        "nodes": 10,
        "guests": 1_000,
        "osds": 100,
        "ha": 12,
        "tasks": 50,
        "pool_members": 50,
        "replication": 8,
        "backups": 80,
        "snapshots": 100,
        "backup_jobs": 4,
        "ha_groups": 4,
        "fw_guest_cap": 256,
    },
    "big": {
        "nodes": 20,
        "guests": 2_000,
        "osds": 500,
        "ha": 24,
        "tasks": 100,
        "pool_members": 100,
        "replication": 16,
        "backups": 160,
        "snapshots": 200,
        "backup_jobs": 6,
        "ha_groups": 6,
        "fw_guest_cap": 384,
    },
}


def _size_spec(profile_name: str) -> dict[str, int]:
    if profile_name in _CLUSTER_SIZE_SPECS:
        return dict(_CLUSTER_SIZE_SPECS[profile_name])
    if profile_name in {"medium", "ha-demo"}:
        return dict(_CLUSTER_SIZE_SPECS["small"])
    return {
        "nodes": 1,
        "guests": 0,
        "osds": 0,
        "ha": 0,
        "tasks": 0,
        "pool_members": 0,
        "replication": 0,
        "backups": 0,
        "snapshots": 0,
        "backup_jobs": 0,
        "ha_groups": 1,
        "fw_guest_cap": 10_000,
    }


def lab_profile() -> SeedProfile:
    """Single-node fixture used by unit/surface tests (not a DATA UI button)."""

    node = _node("pve01")
    resources = (
        _resource(
            node,
            "qemu",
            "100",
            {
                "name": "demo",
                "status": "stopped",
                "agent": {"files": {"/etc/hostname": "demo\n"}},
            },
        ),
        _resource(
            node,
            "qemu",
            "101",
            {
                "name": "worker",
                "status": "stopped",
                "agent": {"files": {"/etc/hostname": "worker\n"}},
            },
        ),
        _resource(
            node,
            "lxc",
            "200",
            {
                "name": "service",
                "status": "stopped",
                "agent": {"files": {"/etc/hostname": "service\n"}},
            },
        ),
        _resource(
            node,
            "storage",
            "local",
            {
                "content": ["iso", "backup", "vztmpl"],
                "status": "available",
                "total_bytes": 100 * 1024**3,
                "used_bytes": 12 * 1024**3,
                "plugintype": "dir",
                "disk": 12 * 1024**3,
                "maxdisk": 100 * 1024**3,
            },
        ),
        _resource(
            node,
            "storage",
            "local-lvm",
            {
                "content": ["images", "rootdir"],
                "status": "available",
                "total_bytes": 500 * 1024**3,
                "used_bytes": 64 * 1024**3,
                "plugintype": "lvmthin",
                "disk": 64 * 1024**3,
                "maxdisk": 500 * 1024**3,
            },
        ),
        _resource(
            node,
            "storage",
            "ceph",
            {
                "content": ["images", "rootdir"],
                "status": "available",
                "shared": True,
                "total_bytes": 3 * 1024**4,
                "used_bytes": 120 * 1024**3,
                "plugintype": "rbd",
                "disk": 120 * 1024**3,
                "maxdisk": 3 * 1024**4,
            },
        ),
        _resource(node, "pool", "lab", {"members": ["100", "200"], "comment": "Lab pool"}),
        _resource(node, "ha", "vm:100", {"state": "started", "group": "primary"}),
        *(
            _resource(
                node,
                "ceph-osd",
                f"osd.{index}",
                {
                    "osd_id": index,
                    "status": "up",
                    "in": 1,
                    "weight": 1.0,
                    "device_class": "hdd",
                    "dev": f"/dev/sd{chr(ord('b') + index)}",
                },
            )
            for index in range(3)
        ),
    )
    tasks = (_completed_task(1, "qmstart", "100"), _completed_task(2, "qmstop", "100"))
    return SeedProfile("lab", (node,), resources, tasks)


def _sized_cluster_profile(name: str, *, overrides: dict[str, int] | None = None) -> SeedProfile:
    """Build a proportional multi-node cluster (small / large / big)."""

    spec = dict(_CLUSTER_SIZE_SPECS[name])
    if overrides:
        spec.update(overrides)
    node_count = int(spec["nodes"])
    guest_count = int(spec["guests"])
    nodes = tuple(_node(f"pve{index}") for index in range(1, node_count + 1))
    guests: list[SeedResource] = []
    guest_pairs: list[tuple[str, str]] = []
    ha_sids: list[str] = []
    for index in range(guest_count):
        node = nodes[index % node_count]
        # ~75% qemu / ~25% lxc
        kind = "lxc" if index % 4 == 0 else "qemu"
        vmid = str(100 + index)
        status = "running" if index % 7 == 0 else "stopped"
        guests.append(_resource(node, kind, vmid, {"name": f"guest-{vmid}", "status": status}))
        if kind == "qemu" and len(guest_pairs) < max(int(spec["tasks"]), 1):
            guest_pairs.append((node.name, vmid))
        if len(ha_sids) < int(spec["ha"]):
            if kind == "lxc":
                ha_sids.append(f"ct:{vmid}")
            elif index % 3 == 1:
                ha_sids.append(f"vm:{vmid}")
    for index in range(guest_count):
        if len(ha_sids) >= int(spec["ha"]):
            break
        if index % 4 == 0:
            continue
        sid = f"vm:{100 + index}"
        if sid not in ha_sids:
            ha_sids.append(sid)

    pool_members = tuple(
        str(100 + index) for index in range(min(int(spec["pool_members"]), guest_count))
    )
    pool_id = {"small": "development", "large": "production", "big": "production"}[name]
    infra = _cluster_infra(
        nodes,
        osd_count=int(spec["osds"]),
        ha_sids=tuple(ha_sids[: int(spec["ha"])]),
        pool_id=pool_id,
        pool_members=pool_members,
        guest_count=guest_count,
    )
    # Extra pools for larger sizes (members are disjoint samples).
    if name == "large" and int(spec["guests"]) >= 1_000:
        infra.append(
            _resource(
                nodes[0],
                "pool",
                "staging",
                {
                    "members": [str(100 + index) for index in range(20, 40)],
                    "comment": "Pool staging",
                },
            )
        )
    elif name == "big":
        infra.extend(
            [
                _resource(
                    nodes[0],
                    "pool",
                    "staging",
                    {
                        "members": [str(100 + index) for index in range(40, 70)],
                        "comment": "Pool staging",
                    },
                ),
                _resource(
                    nodes[0],
                    "pool",
                    "development",
                    {
                        "members": [str(100 + index) for index in range(70, 100)],
                        "comment": "Pool development",
                    },
                ),
            ]
        )
    tasks = _seed_tasks_for_guests(nodes, guest_pairs, limit=int(spec["tasks"]))
    return SeedProfile(name, nodes, tuple(guests) + tuple(infra), tasks)


def small_profile() -> SeedProfile:
    """DATA UI: 3 hosts x 50 guests."""

    return _sized_cluster_profile("small")


def large_profile(*, node_count: int = 10, resource_count: int = 1_000) -> SeedProfile:
    """DATA UI: 10 hosts x 1000 guests (overrides allowed for CLI stress)."""

    if node_count < 1 or resource_count < 1:
        raise ValueError("large profile counts must be positive")
    if node_count == 10 and resource_count == 1_000:
        return _sized_cluster_profile("large")
    scale = max(resource_count / 1_000, node_count / 10)
    return _sized_cluster_profile(
        "large",
        overrides={
            "nodes": node_count,
            "guests": resource_count,
            "osds": max(10, round(100 * scale)),
            "ha": max(3, round(12 * scale)),
            "tasks": max(12, round(50 * scale)),
            "pool_members": max(12, min(resource_count, round(50 * scale))),
        },
    )


def big_profile() -> SeedProfile:
    """DATA UI: 20 hosts x 2000 guests."""

    return _sized_cluster_profile("big")


def medium_profile() -> SeedProfile:
    """Compatibility alias for the small (3x50) cluster."""

    profile = small_profile()
    return SeedProfile("medium", profile.nodes, profile.resources, profile.tasks)


def ha_demo_profile() -> SeedProfile:
    profile = small_profile()
    return SeedProfile("ha-demo", profile.nodes, profile.resources, profile.tasks)


def minimal_profile() -> SeedProfile:
    node = _node("pve01")
    resources = (
        _resource(node, "storage", "local", {"content": ["iso", "backup"], "status": "available"}),
        _resource(
            node, "storage", "local-lvm", {"content": ["images", "rootdir"], "status": "available"}
        ),
    )
    return SeedProfile("minimal", (node,), resources)


def broken_storage_profile() -> SeedProfile:
    profile = lab_profile()
    resources = tuple(
        _resource(
            next(node for node in profile.nodes if node.id == resource.node_id),
            resource.kind,
            resource.external_id,
            {**resource.state, "status": "offline", "error": "simulated I/O failure"}
            if resource.kind == "storage" and resource.external_id == "local-lvm"
            else resource.state,
        )
        for resource in profile.resources
    )
    return SeedProfile("broken-storage", profile.nodes, resources, profile.tasks)


def build_profile(name: str, *, large_nodes: int = 10, large_resources: int = 1_000) -> SeedProfile:
    if name == "lab":
        return lab_profile()
    if name == "small":
        return small_profile()
    if name == "medium":
        return medium_profile()
    if name == "large":
        return large_profile(node_count=large_nodes, resource_count=large_resources)
    if name == "big":
        return big_profile()
    if name == "ha-demo":
        return ha_demo_profile()
    if name == "broken-storage":
        return broken_storage_profile()
    if name == "minimal":
        return minimal_profile()
    if name == "demo-cluster":
        from app.simulation.demo_cluster import demo_cluster_profile

        return demo_cluster_profile()
    raise ValueError(f"unknown seed profile: {name}")


def _storage_type(resource: SeedResource) -> str:
    configured = resource.state.get("storage_type")
    if isinstance(configured, str) and configured:
        return configured
    if resource.external_id.startswith("local"):
        if "lvm" in resource.external_id:
            return "lvmthin"
        if "zfs" in resource.external_id:
            return "zfspool"
        return "dir"
    if resource.external_id.startswith("ceph"):
        return "rbd"
    if resource.external_id.startswith("nfs"):
        return "nfs"
    return "dir"


def _storage_capacity(resource: SeedResource) -> tuple[int | None, int | None]:
    total = resource.state.get("total_bytes", resource.state.get("capacity_bytes"))
    used = resource.state.get("used_bytes")
    total_bytes = int(total) if isinstance(total, int) else None
    used_bytes = int(used) if isinstance(used, int) else None
    return total_bytes, used_bytes


async def clear_simulation_state(connection: Connection) -> None:
    """Remove all mutable simulator state so a seed/reset never fails on leftovers.

    API-created guests, storages, users, groups, roles, ACL/tokens and custom
    realms must not block "Reset to minimal" / reseed. Builtin auth realms
    (`pam`, `pve`, `test`) are kept because principals reference them.
    """
    for statement in (
        "DELETE FROM task_logs",
        "DELETE FROM task_events",
        "DELETE FROM resource_locks",
        "DELETE FROM tasks",
        "DELETE FROM pool_members",
        "DELETE FROM backups",
        "DELETE FROM snapshots",
        "DELETE FROM storage_contents",
        "DELETE FROM vm_disks",
        "DELETE FROM vm_network_interfaces",
        "DELETE FROM virtual_machines",
        "DELETE FROM containers",
        "DELETE FROM storages",
        "DELETE FROM pools",
        "DELETE FROM resources",
        "DELETE FROM nodes",
        "DELETE FROM openid_pending",
        "DELETE FROM tfa_entries",
        "DELETE FROM group_acl_entries",
        "DELETE FROM identity_group_members",
        "DELETE FROM acl_entries",
        "DELETE FROM api_tokens",
        "DELETE FROM auth_tickets",
        "DELETE FROM identity_groups",
        "DELETE FROM principals",
        "DELETE FROM roles",
        "DELETE FROM realms WHERE name NOT IN ('pam', 'pve', 'test')",
        "DELETE FROM fault_injections",
        "DELETE FROM scenario_rules",
        "DELETE FROM audit_events",
    ):
        await connection.execute(statement)
    await connection.execute(
        """UPDATE clusters
        SET name = 'pve-simulator',
            metadata = '{}'::jsonb,
            updated_at = now()
        WHERE id = $1""",
        CLUSTER_ID,
    )


async def simulation_state_summary(connection: Connection) -> dict[str, object]:
    row = await connection.fetchrow(
        """SELECT
            c.name AS cluster_name,
            COALESCE(c.metadata->>'profile', 'unknown') AS profile,
            (SELECT count(*)::int FROM nodes) AS nodes,
            (SELECT count(*)::int FROM resources WHERE kind = 'qemu') AS qemu,
            (SELECT count(*)::int FROM resources WHERE kind = 'lxc') AS lxc,
            (SELECT count(*)::int FROM resources WHERE kind = 'ceph-osd') AS ceph_osds,
            (SELECT count(*)::int FROM resources WHERE kind = 'storage') AS storages,
            (SELECT count(*)::int FROM backups) AS backups,
            (SELECT count(*)::int FROM tasks) AS tasks,
            (SELECT count(*)::int FROM task_logs) AS task_logs,
            (SELECT count(*)::int FROM snapshots) AS snapshots,
            (SELECT count(*)::int FROM principals) AS principals,
            COALESCE(
                (
                    SELECT sum(capacity_bytes)::bigint
                    FROM storages
                    WHERE storage_type IN ('ceph', 'rbd')
                       OR storage_id LIKE 'ceph%'
                ),
                0
            ) AS ceph_capacity_bytes
        FROM clusters c
        WHERE c.id = $1""",
        CLUSTER_ID,
    )
    if row is None:
        return {"profile": "unknown", "loaded": False}
    payload = dict(row)
    payload["loaded"] = payload["profile"] in {"small", "large", "big", "demo-cluster"}
    payload["ceph_capacity_pib"] = round((payload.get("ceph_capacity_bytes") or 0) / 1024**5, 2)
    return payload


async def apply_seed(connection: Connection, profile: SeedProfile) -> None:
    async with connection.transaction():
        await clear_simulation_state(connection)
        await connection.execute(
            """UPDATE clusters
            SET name = $2,
                metadata = $3::jsonb,
                updated_at = now()
            WHERE id = $1""",
            CLUSTER_ID,
            "prod-pve-cluster" if profile.name == "demo-cluster" else "pve-simulator",
            json.dumps(
                {
                    "profile": profile.name,
                    "nodes": len(profile.nodes),
                    "resources": len(profile.resources),
                    **cluster_domain_metadata(profile),
                },
                sort_keys=True,
            ),
        )
        slim_guests = profile.name in {"large", "big"}
        osd_counts_by_node: dict[uuid.UUID, int] = {}
        for resource in profile.resources:
            if resource.kind == "ceph-osd":
                osd_counts_by_node[resource.node_id] = (
                    osd_counts_by_node.get(resource.node_id, 0) + 1
                )
        await connection.executemany(
            "INSERT INTO nodes(id, name, status, metadata) VALUES($1, $2, $3, $4::jsonb)",
            [
                (
                    node.id,
                    node.name,
                    node.status,
                    json.dumps(
                        {
                            "ops": default_node_ops_for_seed(
                                node.name,
                                node_index=index,
                                node_count=len(profile.nodes),
                                osds_per_node=int(osd_counts_by_node.get(node.id, 0)),
                            )
                        },
                        sort_keys=True,
                    ),
                )
                for index, node in enumerate(profile.nodes)
            ],
        )
        await connection.executemany(
            """INSERT INTO resources(id, node_id, kind, external_id, state)
            VALUES($1, $2, $3, $4, $5::jsonb)""",
            [
                (
                    resource.id,
                    resource.node_id,
                    resource.kind,
                    resource.external_id,
                    json.dumps(_seed_resource_state(resource, slim=slim_guests), sort_keys=True),
                )
                for resource in profile.resources
            ],
        )
        qemu = [resource for resource in profile.resources if resource.kind == "qemu"]
        if qemu:
            await connection.executemany(
                """INSERT INTO virtual_machines(resource_id, cluster_id, vmid, config)
                VALUES($1, 'dc760c47-d8d7-57e6-9404-f0c6f2395d8f', $2, $3::jsonb)""",
                [
                    (
                        resource.id,
                        int(resource.external_id),
                        json.dumps(
                            _seed_resource_state(resource, slim=slim_guests), sort_keys=True
                        ),
                    )
                    for resource in qemu
                ],
            )
        containers = [resource for resource in profile.resources if resource.kind == "lxc"]
        if containers:
            await connection.executemany(
                """INSERT INTO containers(resource_id, cluster_id, vmid, config)
                VALUES($1, 'dc760c47-d8d7-57e6-9404-f0c6f2395d8f', $2, $3::jsonb)""",
                [
                    (
                        resource.id,
                        int(resource.external_id),
                        json.dumps(
                            _seed_resource_state(resource, slim=slim_guests), sort_keys=True
                        ),
                    )
                    for resource in containers
                ],
            )
        storages = [resource for resource in profile.resources if resource.kind == "storage"]
        if storages:
            await connection.executemany(
                """INSERT INTO storages(
                    resource_id, cluster_id, storage_id, storage_type, shared,
                    capacity_bytes, used_bytes, config
                ) VALUES($1, $2, $3, $4, $5, $6, $7, $8::jsonb)""",
                [
                    (
                        resource.id,
                        str(CLUSTER_ID),
                        resource.external_id,
                        _storage_type(resource),
                        bool(resource.state.get("shared", False)),
                        *_storage_capacity(resource),
                        json.dumps(
                            _seed_resource_state(resource, slim=slim_guests), sort_keys=True
                        ),
                    )
                    for resource in storages
                ],
            )
            contents = [
                (
                    stable_id(f"content:{resource.external_id}:{content}"),
                    resource.id,
                    f"{resource.external_id}:{content}/seeded",
                    str(content),
                )
                for resource in storages
                for content in _string_list(resource.state, "content")
            ]
            if contents:
                await connection.executemany(
                    """INSERT INTO storage_contents(
                        id, storage_resource_id, volume_id, content_type
                    ) VALUES($1, $2, $3, $4)""",
                    contents,
                )
        pools = [resource for resource in profile.resources if resource.kind == "pool"]
        if pools:
            await connection.executemany(
                """INSERT INTO pools(id, cluster_id, pool_id, metadata)
                VALUES($1, 'dc760c47-d8d7-57e6-9404-f0c6f2395d8f', $2, $3::jsonb)""",
                [
                    (resource.id, resource.external_id, json.dumps(resource.state, sort_keys=True))
                    for resource in pools
                ],
            )
            members = [
                (pool.id, member.id)
                for pool in pools
                for external_id in _string_list(pool.state, "members")
                for member in profile.resources
                if member.external_id == external_id and member.kind in {"qemu", "lxc"}
            ]
            if members:
                await connection.executemany(
                    "INSERT INTO pool_members(pool_id, resource_id) VALUES($1, $2)", members
                )
        if profile.tasks:
            await connection.executemany(
                """INSERT INTO tasks(id, upid, status, payload, task_type, progress, result)
                VALUES($1, $2, 'success', $3::jsonb, $4, 100, '{\"seeded\":true}'::jsonb)""",
                [
                    (task.id, task.upid, json.dumps(task.payload, sort_keys=True), task.task_type)
                    for task in profile.tasks
                ],
            )
        await connection.execute(
            """INSERT INTO principals(id, name, password_hash, realm_name)
            VALUES($1, 'root@pam', $2, 'pam')
            ON CONFLICT (name) DO UPDATE SET password_hash=EXCLUDED.password_hash,
            realm_name=EXCLUDED.realm_name""",
            stable_id("principal:root@pam"),
            hash_secret("secret", salt=b"pve-simulator-v1"),
        )
        await connection.execute(
            """INSERT INTO api_tokens(principal_id, token_id, secret_hash, privileges)
            VALUES($1, 'automation', $2, $3)
            ON CONFLICT (principal_id, token_id) DO UPDATE
            SET secret_hash=EXCLUDED.secret_hash, privileges=EXCLUDED.privileges""",
            stable_id("principal:root@pam"),
            hash_secret("automation-secret", salt=b"pve-token-seed-v1"),
            ["VM.Audit", "VM.PowerMgmt", "Sys.Audit"],
        )
        auditor_id = stable_id("principal:auditor@pve")
        await connection.execute(
            """INSERT INTO principals(id, name, password_hash, realm_name)
            VALUES($1, 'auditor@pve', $2, 'pve')
            ON CONFLICT (name) DO UPDATE SET password_hash=EXCLUDED.password_hash,
            realm_name=EXCLUDED.realm_name""",
            auditor_id,
            hash_secret("auditor-secret", salt=b"pve-auditor-v1"),
        )
        await connection.execute(
            """INSERT INTO roles(name, privileges)
            VALUES('PVEAuditor', $1)
            ON CONFLICT (name) DO UPDATE SET privileges=EXCLUDED.privileges""",
            ["Sys.Audit", "VM.Audit"],
        )
        await connection.execute(
            "DELETE FROM acl_entries WHERE principal_id=$1 AND role_name='PVEAuditor'",
            auditor_id,
        )
        auditor_group_id = await connection.fetchval(
            """INSERT INTO identity_groups(id, group_id, comment)
            VALUES($1, 'auditors', 'Read-only operators')
            ON CONFLICT (group_id) DO UPDATE SET comment=EXCLUDED.comment
            RETURNING id""",
            stable_id("group:auditors"),
        )
        await connection.execute(
            """INSERT INTO identity_group_members(group_id, principal_id)
            VALUES($1, $2) ON CONFLICT DO NOTHING""",
            auditor_group_id,
            auditor_id,
        )
        await connection.execute(
            """INSERT INTO group_acl_entries(group_id, role_name, path, propagate)
            VALUES($1, 'PVEAuditor', '/', true)
            ON CONFLICT (group_id, role_name, path) DO UPDATE
            SET propagate=EXCLUDED.propagate""",
            auditor_group_id,
        )
        await connection.execute(
            """INSERT INTO api_tokens(principal_id, token_id, secret_hash, privileges)
            VALUES($1, 'readonly', $2, $3)
            ON CONFLICT (principal_id, token_id) DO UPDATE
            SET secret_hash=EXCLUDED.secret_hash, privileges=EXCLUDED.privileges""",
            auditor_id,
            hash_secret("readonly-secret", salt=b"pve-readonly-v1"),
            ["Sys.Audit", "VM.Audit"],
        )
        for username, role_name, privileges, acl_path, token_id, token_secret in (
            (
                "operator@pve",
                "PVEVMOperator",
                ["VM.Audit", "VM.PowerMgmt"],
                "/vms",
                "operator",
                "operator-secret",
            ),
            (
                "storage@pve",
                "PVEStorageUser",
                ["Datastore.Audit", "Datastore.AllocateSpace"],
                "/storage",
                "storage",
                "storage-secret",
            ),
        ):
            principal_id = stable_id(f"principal:{username}")
            await connection.execute(
                """INSERT INTO principals(id, name, password_hash, realm_name)
                VALUES($1, $2, $3, 'pve')
                ON CONFLICT (name) DO UPDATE SET password_hash=EXCLUDED.password_hash,
                realm_name=EXCLUDED.realm_name""",
                principal_id,
                username,
                hash_secret(f"{username}-password", salt=f"seed:{username}".encode()),
            )
            await connection.execute(
                """INSERT INTO roles(name, privileges) VALUES($1, $2)
                ON CONFLICT (name) DO UPDATE SET privileges=EXCLUDED.privileges""",
                role_name,
                privileges,
            )
            await connection.execute(
                """INSERT INTO acl_entries(principal_id, role_name, path, propagate)
                VALUES($1, $2, $3, true)
                ON CONFLICT (principal_id, role_name, path) DO UPDATE
                SET propagate=EXCLUDED.propagate""",
                principal_id,
                role_name,
                acl_path,
            )
            await connection.execute(
                """INSERT INTO api_tokens(principal_id, token_id, secret_hash, privileges)
                VALUES($1, $2, $3, $4)
                ON CONFLICT (principal_id, token_id) DO UPDATE
                SET secret_hash=EXCLUDED.secret_hash, privileges=EXCLUDED.privileges,
                privilege_separation=true""",
                principal_id,
                token_id,
                hash_secret(token_secret, salt=f"token:{username}".encode()),
                privileges,
            )
        if profile.name == "demo-cluster":
            await _apply_demo_cluster_extras(connection, profile)
        elif profile.name in {"lab", "small", "large", "big", "medium", "ha-demo"}:
            await _seed_profile_artifacts(connection, profile)


async def _seed_profile_artifacts(connection: Connection, profile: SeedProfile) -> None:
    """Proportional backups / snapshots / task logs for DATA cluster sizes."""

    scale = _size_spec(profile.name)
    names = {node.id: node.name for node in profile.nodes}
    guests = [resource for resource in profile.resources if resource.kind in {"qemu", "lxc"}]
    if not guests:
        return

    backup_limit = min(int(scale.get("backups", 0)), len(guests))
    snap_limit = min(int(scale.get("snapshots", 0)), len(guests))
    storage_rows = await connection.fetch(
        """SELECT s.resource_id, s.storage_id FROM storages s
        WHERE s.storage_id IN ('local', 'ceph') ORDER BY s.storage_id"""
    )
    storage_by_id = {str(row["storage_id"]): row["resource_id"] for row in storage_rows}
    fallback = storage_by_id.get("local") or storage_by_id.get("ceph")
    if fallback is not None and backup_limit:
        backups: list[tuple[uuid.UUID, uuid.UUID, uuid.UUID, str, int, str]] = []
        for index, resource in enumerate(guests[:backup_limit]):
            storage_id = "ceph" if index % 3 == 0 and "ceph" in storage_by_id else "local"
            storage_resource = storage_by_id.get(storage_id, fallback)
            volume_id = (
                f"{storage_id}:backup/vzdump-{resource.kind}-{resource.external_id}"
                f"-2026_07_18-{index:04d}.vma.zst"
            )
            backups.append(
                (
                    stable_id(f"backup:{profile.name}:{resource.external_id}:{index}"),
                    resource.id,
                    storage_resource,
                    volume_id,
                    (4 + (index % 20)) * 1024**3,
                    json.dumps(
                        {
                            "mode": "snapshot",
                            "node": names[resource.node_id],
                            "notes-template": "{{guestname}}",
                        },
                        sort_keys=True,
                    ),
                )
            )
        if backups:
            await connection.executemany(
                """INSERT INTO backups(
                    id, resource_id, storage_resource_id, volume_id, size_bytes, metadata
                ) VALUES($1, $2, $3, $4, $5, $6::jsonb)""",
                backups,
            )

    if snap_limit:
        snapshots: list[tuple[uuid.UUID, uuid.UUID, str, str | None, str, str]] = []
        for index, resource in enumerate(guests[:snap_limit]):
            snap_name = "baseline"
            snapshots.append(
                (
                    stable_id(f"snapshot:{profile.name}:{resource.external_id}:{snap_name}"),
                    resource.id,
                    snap_name,
                    None,
                    "Seeded snapshot",
                    json.dumps({"vmstate": index % 2 == 0}, sort_keys=True),
                )
            )
        if snapshots:
            await connection.executemany(
                """INSERT INTO snapshots(id, resource_id, name, parent_name, description, state)
                VALUES($1, $2, $3, $4, $5, $6::jsonb)""",
                snapshots,
            )

    if profile.tasks:
        logs: list[tuple[uuid.UUID, str]] = []
        for task_index, task in enumerate(profile.tasks, start=1):
            for message in (f"starting {task.task_type}", f"finished {task.task_type} OK"):
                logs.append((task.id, message))
            if task_index >= 40:
                break
        if logs:
            await connection.executemany(
                "INSERT INTO task_logs(task_id, message) VALUES($1, $2)",
                logs,
            )


async def _apply_demo_cluster_extras(connection: Connection, profile: SeedProfile) -> None:
    names = {node.id: node.name for node in profile.nodes}
    guests = [resource for resource in profile.resources if resource.kind in {"qemu", "lxc"}]

    disks: list[tuple[uuid.UUID, uuid.UUID, str, str, int, str]] = []
    for index, resource in enumerate(guests):
        node_name = names[resource.node_id]
        disk_count = 1 + (index % 3)
        for disk_index in range(disk_count):
            device = "rootfs" if resource.kind == "lxc" and disk_index == 0 else f"scsi{disk_index}"
            storage_id = "ceph-prod" if (index + disk_index) % 4 == 0 else f"local-lvm-{node_name}"
            size_bytes = (20 + (index % 9) * 10 + disk_index * 15) * 1024**3
            disks.append(
                (
                    stable_id(f"disk:{resource.external_id}:{device}"),
                    resource.id,
                    device,
                    storage_id,
                    size_bytes,
                    json.dumps({"format": "raw" if disk_index else "qcow2"}, sort_keys=True),
                )
            )
    if disks:
        await connection.executemany(
            """INSERT INTO vm_disks(id, resource_id, device, storage_id, size_bytes, metadata)
            VALUES($1, $2, $3, $4, $5, $6::jsonb)""",
            disks,
        )

    interfaces: list[tuple[uuid.UUID, uuid.UUID, str, str]] = []
    for index, resource in enumerate(guests):
        interfaces.append(
            (
                stable_id(f"net:{resource.external_id}:net0"),
                resource.id,
                "net0",
                json.dumps(
                    {
                        "bridge": "vmbr0",
                        "firewall": index % 7 != 0,
                        "tag": (index % 12) * 10 or None,
                    },
                    sort_keys=True,
                ),
            )
        )
        if index % 5 == 0:
            interfaces.append(
                (
                    stable_id(f"net:{resource.external_id}:net1"),
                    resource.id,
                    "net1",
                    json.dumps({"bridge": "vmbr1", "firewall": True}, sort_keys=True),
                )
            )
    if interfaces:
        await connection.executemany(
            """INSERT INTO vm_network_interfaces(id, resource_id, device, config)
            VALUES($1, $2, $3, $4::jsonb)""",
            interfaces,
        )

    snapshots: list[tuple[uuid.UUID, uuid.UUID, str, str | None, str, str]] = []
    for index, resource in enumerate(guests):
        if index % 7 != 0:
            continue
        for snap_index in range(1 + (index % 3)):
            snap_name = f"snap-{snap_index:02d}"
            snapshots.append(
                (
                    stable_id(f"snapshot:{resource.external_id}:{snap_name}"),
                    resource.id,
                    snap_name,
                    None if snap_index == 0 else f"snap-{snap_index - 1:02d}",
                    f"Automated snapshot #{snap_index}",
                    json.dumps({"vmstate": index % 2 == 0}, sort_keys=True),
                )
            )
    if snapshots:
        await connection.executemany(
            """INSERT INTO snapshots(id, resource_id, name, parent_name, description, state)
            VALUES($1, $2, $3, $4, $5, $6::jsonb)""",
            snapshots,
        )

    storage_rows = await connection.fetch(
        """SELECT s.resource_id, s.storage_id, n.name AS node_name
        FROM storages s
        JOIN resources r ON r.id = s.resource_id
        JOIN nodes n ON n.id = r.node_id
        WHERE s.storage_id LIKE 'backup-%' OR s.storage_id IN ('ceph-prod', 'nfs-backup')"""
    )
    storage_by_id = {row["storage_id"]: row["resource_id"] for row in storage_rows}
    storage_by_node = {
        str(row["node_name"]): row["resource_id"]
        for row in storage_rows
        if str(row["storage_id"]).startswith("backup-")
    }
    fallback_backup = storage_by_id.get("nfs-backup") or storage_by_id.get("ceph-prod")
    if fallback_backup is not None:
        backups: list[tuple[uuid.UUID, uuid.UUID | None, uuid.UUID, str, int, str]] = []
        qemu_guests = [resource for resource in guests if resource.kind == "qemu"]
        for index, resource in enumerate(qemu_guests):
            node_name = names[resource.node_id]
            backup_storage = storage_by_node.get(node_name, fallback_backup)
            volume_id = f"backup/vzdump-qemu-{resource.external_id}-2026_07_15-{index:04d}.vma.zst"
            backups.append(
                (
                    stable_id(f"backup:{resource.external_id}:{index}"),
                    resource.id,
                    backup_storage,
                    volume_id,
                    (8 + (index % 40)) * 1024**3,
                    json.dumps(
                        {
                            "mode": "snapshot" if index % 3 else "suspend",
                            "notes-template": "Daily backup",
                            "node": node_name,
                        },
                        sort_keys=True,
                    ),
                )
            )
        if backups:
            await connection.executemany(
                """INSERT INTO backups(
                    id, resource_id, storage_resource_id, volume_id, size_bytes, metadata
                ) VALUES($1, $2, $3, $4, $5, $6::jsonb)""",
                backups,
            )

    guest_list = sorted(
        guests, key=lambda resource: (names[resource.node_id], resource.external_id)
    )
    extra_tasks: list[tuple[uuid.UUID, str, str, str, str]] = []
    for index in range(251, 321):
        guest = guest_list[(index - 251) % len(guest_list)]
        node_name = names[guest.node_id]
        node = next(node for node in profile.nodes if node.name == node_name)
        task_type = ("vzdump", "qmmigrate", "qmstart", "cephosd")[index % 4]
        status = "running" if index % 17 == 0 else "error" if index % 23 == 0 else "success"
        extra_tasks.append(
            (
                stable_id(f"demo-task-extra:{index}"),
                f"UPID:{node.name}:{index:07X}:{index:07X}:68{index:06X}:"
                f"{task_type}:{guest.external_id}:operator@pve:",
                status,
                json.dumps(
                    {"resource_id": guest.external_id, "node": node.name},
                    sort_keys=True,
                ),
                task_type,
            )
        )
    if extra_tasks:
        await connection.executemany(
            """INSERT INTO tasks(id, upid, status, payload, task_type, progress, result, error)
            VALUES($1, $2, $3, $4::jsonb, $5,
                CASE WHEN $3 = 'success' THEN 100 WHEN $3 = 'running' THEN 45 ELSE 0 END,
                CASE WHEN $3 = 'success' THEN '{\"seeded\":true}'::jsonb ELSE NULL END,
                CASE WHEN $3 = 'error' THEN 'simulated backup failure' ELSE NULL END)""",
            extra_tasks,
        )

    task_rows = await connection.fetch(
        "SELECT id, task_type, payload FROM tasks ORDER BY upid LIMIT 180"
    )
    logs: list[tuple[uuid.UUID, str]] = []
    for task in task_rows:
        payload = task["payload"]
        if isinstance(payload, dict):
            resource_id = payload.get("resource_id", "unknown")
            node_label = payload.get("node", "pve01")
        else:
            resource_id = "unknown"
            node_label = "unknown"
        messages: tuple[str, ...] = (
            f"starting task {task['task_type']} on {node_label}",
            f"processing guest {resource_id}",
            f"task {task['task_type']} finished successfully",
        )
        if task["task_type"] == "vzdump":
            messages = (
                f"INFO: starting backup of VM {resource_id} on {node_label}",
                f"INFO: snapshot create VM {resource_id}",
                f"INFO: archive file size: {(8 + hash(str(task['id'])) % 40)}GB",
                "INFO: Backup finished successfully",
            )
        logs.extend((task["id"], message) for message in messages)
    if logs:
        await connection.executemany(
            "INSERT INTO task_logs(task_id, message) VALUES($1, $2)",
            logs,
        )

    demo_users = (
        ("admin@pve", "PVEAdmin", ["/"], ["Sys.Modify", "Sys.Audit", "Datastore.Allocate"]),
        ("devops@pve", "PVEAdmin", ["/vms"], ["Sys.Audit", "VM.Allocate", "VM.PowerMgmt"]),
        (
            "backup-operator@pve",
            "PVEDatastoreAdmin",
            ["/storage"],
            ["Datastore.Allocate", "Datastore.Audit"],
        ),
        ("ceph-monitor@pve", "PVEAuditor", ["/"], ["Sys.Audit", "Datastore.Audit"]),
        ("junior@pve", "PVEAuditor", ["/vms"], ["Sys.Audit", "VM.Audit"]),
        ("security@pve", "PVEAuditor", ["/access"], ["Sys.Audit", "User.Modify"]),
    )
    for username, role_name, acl_paths, privileges in demo_users:
        principal_id = stable_id(f"principal:{username}")
        await connection.execute(
            """INSERT INTO principals(id, name, password_hash, realm_name)
            VALUES($1, $2, $3, 'pve')
            ON CONFLICT (name) DO UPDATE SET password_hash=EXCLUDED.password_hash,
            realm_name=EXCLUDED.realm_name""",
            principal_id,
            username,
            hash_secret(f"{username}-password", salt=f"seed:{username}".encode()),
        )
        await connection.execute(
            """INSERT INTO roles(name, privileges) VALUES($1, $2)
            ON CONFLICT (name) DO UPDATE SET privileges=EXCLUDED.privileges""",
            role_name,
            privileges,
        )
        for acl_path in acl_paths:
            await connection.execute(
                """INSERT INTO acl_entries(principal_id, role_name, path, propagate)
                VALUES($1, $2, $3, true)
                ON CONFLICT (principal_id, role_name, path) DO UPDATE
                SET propagate=EXCLUDED.propagate""",
                principal_id,
                role_name,
                acl_path,
            )


async def seed_url(
    database_url: str,
    profile_name: str = "small",
    *,
    large_nodes: int = 10,
    large_resources: int = 10_000,
) -> dict[str, object]:
    connection = await asyncpg.connect(database_url)
    try:
        profile = build_profile(
            profile_name, large_nodes=large_nodes, large_resources=large_resources
        )
        await apply_seed(connection, profile)
        return profile.logical_state()
    finally:
        await connection.close()
