variable "vm_name" {
  description = "Domain name, e.g. \"dc1-compute-01\"."
  type        = string
}

variable "memory_mib" {
  description = "Memory in MiB. Sizing is a Phase-0 host/disk-budget decision (buildout-design Section 3) -- no default, pass explicitly."
  type        = number
}

variable "vcpu" {
  description = "Virtual CPU count. No default -- pass explicitly, per the measured Phase-0 CPU budget."
  type        = number
}

variable "pool_name" {
  description = "libvirt_pool name this VM's disk lives in (output of modules/dc-storage-pool)."
  type        = string
}

variable "disk_size_bytes" {
  description = "Blank boot-disk size in bytes. No default -- pass explicitly."
  type        = number
}

variable "network_names" {
  description = <<-EOT
    Ordered list of libvirt_network names (outputs of modules/dc-planes) this
    VM attaches to. Order matters for boot priority -- the FIRST entry is
    given PXE boot priority (see main.tf's boot-order note; MAAS-managed
    node VMs PXE-boot per D-103, they are not given a pre-built OS image).
  EOT
  type        = list(string)
}

variable "interface_macs" {
  description = <<-EOT
    Optional ordered list of MAC addresses, one per network_names entry (same
    order), PINNING each NIC's MAC in config. Empty (the default) lets libvirt
    generate MACs -- acceptable ONLY before a node is enlisted anywhere.

    WHY PINNING EXISTS: measured 2026-07-20/21 -- a tofu/libvirt "in-place"
    domain update (plan 0/N/0, no replace) can silently REGENERATE every
    unpinned NIC MAC. MAAS keys enlisted machines by boot-interface MAC, so
    the drift strands the whole fleet: every PXE boot becomes an unknown node
    and commissioning times out with NO "Performing PXE boot" event (the
    2026-07-21 commissioning incident; adjudication
    docs/audit/commissioning-diag-20260721.txt). Once nodes are enlisted, pin
    their MACs to the live measured values so no future apply can drift them.
    VR-only trap: Roosevelt metal has fixed NIC MACs.
  EOT
  type        = list(string)
  default     = []

  validation {
    condition     = length(var.interface_macs) == 0 || length(var.interface_macs) == length(var.network_names)
    error_message = "interface_macs must be empty or exactly one MAC per network_names entry (partial pinning would silently leave some NICs drift-prone)."
  }

  validation {
    condition     = alltrue([for m in var.interface_macs : can(regex("^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$", m))])
    error_message = "Each interface_macs entry must be a colon-separated 6-byte hex MAC (e.g. 52:54:00:ab:cd:ef)."
  }
}

variable "autostart" {
  description = "Start this domain automatically when the libvirt host boots (D-127 boot matrix). MANUAL (false) for DC containment + node VMs; true for foundational service VMs + edges. Set explicitly per instance in the root -- do not rely on the default."
  type        = bool
  default     = false
}

variable "serial_log_dir" {
  description = <<-EOT
    Directory ON THE LIBVIRT HOST for this node's serial boot log.

    PARAMETERIZED, not hardcoded: modules/opnsense-edge bakes
    "/var/lib/libvirt/vr1/staging" into its serial path, which is a vcloud-only
    literal and silently wrong on any other libvirt host -- under D-123 Model B
    the node VMs live inside vvr1-dc0, a different host entirely. (Backporting
    this parameterization to opnsense-edge is a queued finding.)

    The directory MUST exist and be writable by libvirt on that host, or the
    domain fails to START with "Unable to open file: ... No such file or
    directory" -- measured on the dc0 edge, 2026-07-20.
  EOT
  type        = string
  default     = "/var/lib/libvirt/vr1/staging"
}

variable "osd_disk_size_bytes" {
  description = <<-EOT
    OPT-IN second block device, attached as vdb. 0 (the default) creates NOTHING and
    leaves the domain byte-identical to before this variable existed.

    R1 (D-121 AMENDMENT, RULED 2026-07-27, operator: "Add an OSD volume to node-vm
    (Recommended)"): `bundle.yaml` sets `osd-devices: /dev/vdb`, but every VR1 node was
    built with exactly one device. Measured independently by two instruments -- `virsh
    domblklist` on both racks and MAAS `physicalblockdevice_set` on all 18 nodes. Left
    unfixed the deploy yields ZERO OSDs and `expected-osd-count: 4` is never met.

    SCOPE IS 8 VOLUMES, NOT 18: ceph-osd is placed on the four STORAGE nodes per DC only,
    so only those callers set this. That is precondition 4 of the amendment -- this
    module is SHARED by both DCs, so the change had to be opt-in per role or it would
    plan a change against all 18 domains.
  EOT
  type        = number
  default     = 0

  validation {
    condition     = var.osd_disk_size_bytes >= 0
    error_message = "osd_disk_size_bytes must be 0 (no OSD disk) or a positive byte count."
  }
}
