# tools/qemu/common.sh — sourced helpers for the qemu wrapper scripts.
# Centralizes paths, firmware locations, and the QEMU invocation pattern
# so the per-task scripts (vm-up, vm-build, vm-test-install) stay terse.

set -eu

ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
VMS="$ROOT/.vms"
ISO_DIR="$VMS/iso"
IMG_DIR="$VMS/images"
DISK_DIR="$VMS/disks"
NVRAM_DIR="$VMS/nvram"
KEYS_DIR="$VMS/keys"

# Alpine release pinning.
# ALPINE_VERSION is the full point version; the major.minor part selects
# the release branch directory, the full version names the file. Current
# as of 2026-05: 3.23.4 in main+community.
ALPINE_VERSION="${ALPINE_VERSION:-3.23.4}"
ALPINE_BRANCH="${ALPINE_VERSION%.*}"
ALPINE_ISO_URL="${ALPINE_ISO_URL:-https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_BRANCH}/releases/x86_64/alpine-virt-${ALPINE_VERSION}-x86_64.iso}"
ALPINE_ISO="$ISO_DIR/$(basename "$ALPINE_ISO_URL")"
ALPINE_CLOUD_URL="${ALPINE_CLOUD_URL:-https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_BRANCH}/releases/cloud/generic_alpine-${ALPINE_VERSION}-x86_64-uefi-cloudinit-r0.qcow2}"

OVMF_CODE="/opt/homebrew/share/qemu/edk2-x86_64-code.fd"
OVMF_VARS_TEMPLATE="/opt/homebrew/share/qemu/edk2-i386-vars.fd"

# Apple Silicon: no HVF for x86_64. Use TCG with as much help as we can give it.
# QEMU 11+: pass accel via a separate -accel flag, not as a -machine property
# (thread=multi is an -accel property, not a machine property).
ACCEL_ARGS="-accel tcg,thread=multi"
SMP="${SMP:-4}"
MEM="${MEM:-4G}"

# Forwarded SSH ports.
BUILDER_SSH_PORT="${BUILDER_SSH_PORT:-2222}"
TARGET_SSH_PORT="${TARGET_SSH_PORT:-2223}"

# Common QEMU invocation. Callers add: -drive, -cdrom, -netdev forwards,
# -name, AND a -serial flag (we don't pick one here because daemonized
# and foreground modes want different serial routing).
qemu_base_args() {
    local name="$1"
    local nvram="$NVRAM_DIR/${name}_VARS.fd"
    if [ ! -f "$nvram" ]; then
        cp "$OVMF_VARS_TEMPLATE" "$nvram"
    fi
    cat <<EOF
-name $name
-machine type=q35
$ACCEL_ARGS
-cpu max
-smp $SMP
-m $MEM
-drive if=pflash,format=raw,readonly=on,file=$OVMF_CODE
-drive if=pflash,format=raw,file=$nvram
-rtc base=utc
-device virtio-rng-pci
-vga virtio
-display none
EOF
}

ensure_alpine_iso() {
    if [ ! -f "$ALPINE_ISO" ]; then
        echo "==> downloading Alpine $ALPINE_VERSION ISO ..."
        mkdir -p "$ISO_DIR"
        curl -fL --progress-bar -o "$ALPINE_ISO" "$ALPINE_ISO_URL"
    fi
}

ensure_dirs() {
    mkdir -p "$ISO_DIR" "$IMG_DIR" "$DISK_DIR" "$NVRAM_DIR" "$KEYS_DIR"
}
