#!/bin/bash
# Install Talos Linux as a KVM virtual machine.
# Usage: omv-install-talos <pool> <nettype> <netname> <vmname> <version> <memory_mib> <vcpus> <disksize_gb>
set -e

POOL="$1"
NET_TYPE="$2"
NET_NAME="$3"
VM_NAME="$4"
VERSION="${5#v}"
MEMORY="${6:-4096}"
VCPUS="${7:-2}"
DISK_GB="${8:-20}"

if [ -z "$POOL" ] || [ -z "$NET_TYPE" ] || [ -z "$NET_NAME" ] || [ -z "$VM_NAME" ] || [ -z "$VERSION" ]; then
    echo "Usage: $0 <pool> <nettype> <netname> <vmname> <version> [memory_mib] [vcpus] [disksize_gb]"
    echo "Example: $0 default bridge br0 talos 1.14.2"
    exit 1
fi

# Image Factory schematic: stock Talos plus the siderolabs/qemu-guest-agent extension
SCHEMATIC="ce4c980550dd2ab1b17bbf2b08801c7eb59418eafe8f279833297925d67c7515"

ARCH=$(dpkg --print-architecture)

case "$ARCH" in
    amd64)
        ARCH_ARG="x86_64"
        BOOT_ARG="hd,cdrom"
        ;;
    arm64)
        ARCH_ARG="aarch64"
        BOOT_ARG="hd,cdrom,loader=/usr/share/AAVMF/AAVMF_CODE.no-secboot.fd,loader_type=pflash,nvram.template=/usr/share/AAVMF/AAVMF_VARS.fd"
        ;;
    *)
        echo "Error: Unsupported architecture '$ARCH'. Only amd64 and arm64 are supported."
        exit 1
        ;;
esac

FILENAME="talos-${VERSION}-metal-${ARCH}.iso"
URL="https://factory.talos.dev/image/${SCHEMATIC}/v${VERSION}/metal-${ARCH}.iso"

POOL_PATH=$(virsh pool-dumpxml "$POOL" 2>/dev/null | grep -oP '(?<=<path>)[^<]+' | head -1)
if [ -z "$POOL_PATH" ]; then
    echo "Error: Could not find path for pool '$POOL'."
    exit 1
fi

DISK_PATH="${POOL_PATH}/${VM_NAME}.qcow2"
ISO_PATH="${POOL_PATH}/${FILENAME}"

if [ -f "$DISK_PATH" ]; then
    echo "Error: Disk already exists at '$DISK_PATH'. Remove it first or choose a different VM name."
    exit 1
fi

if virsh dominfo "$VM_NAME" &>/dev/null; then
    echo "Error: A VM named '$VM_NAME' already exists."
    exit 1
fi

echo "=== Talos Linux v${VERSION} VM Installer ==="
echo "Architecture : ${ARCH} (${ARCH_ARG})"
echo "Pool         : ${POOL} (${POOL_PATH})"
echo "VM name      : ${VM_NAME}"
echo "Memory       : ${MEMORY} MiB"
echo "vCPUs        : ${VCPUS}"
echo "Disk         : ${DISK_GB} GB"
echo "Network      : ${NET_TYPE}=${NET_NAME}"
echo ""

if [ ! -f "$ISO_PATH" ]; then
    echo "Downloading ${URL}..."
    if ! wget --progress=dot:giga --output-document="$ISO_PATH" "$URL"; then
        rm -f "$ISO_PATH"
        echo "Error: Download failed. Check that Talos version '${VERSION}' exists."
        exit 1
    fi
    chown libvirt-qemu:kvm "$ISO_PATH" 2>/dev/null || true
    chmod 660 "$ISO_PATH"
else
    echo "ISO already present at '${ISO_PATH}', skipping download."
fi

echo "Creating ${DISK_GB} GB disk image..."
qemu-img create -f qcow2 "$DISK_PATH" "${DISK_GB}G"
chown libvirt-qemu:kvm "$DISK_PATH" 2>/dev/null || true
chmod 660 "$DISK_PATH"
trap "rm -f '$DISK_PATH'" EXIT

echo "Refreshing pool '${POOL}'..."
virsh pool-refresh "$POOL"

VIRT_ARGS=(
    --name "$VM_NAME"
    --memory "$MEMORY"
    --vcpus "$VCPUS"
    --cpu host-passthrough
    --disk "${DISK_PATH},bus=virtio,cache=none,io=native"
    --disk "${ISO_PATH},device=cdrom,bus=scsi,readonly=on"
    --controller scsi,model=virtio-scsi
    --import
    --arch "$ARCH_ARG"
    --os-variant generic
    --metadata "description=Talos Linux v${VERSION}"
    --memballoon none
    --clock offset=utc
    --boot "$BOOT_ARG"
    --channel "unix,target.type=virtio,target.name=org.qemu.guest_agent.0"
    --graphics vnc,listen=0.0.0.0
    --noautoconsole
)

if [ "$NET_TYPE" = "bridge" ]; then
    VIRT_ARGS+=(--network "bridge=${NET_NAME},model=virtio")
else
    VIRT_ARGS+=(--network "network=${NET_NAME},model=virtio")
fi

echo ""
echo "Creating VM '${VM_NAME}'..."
virt-install "${VIRT_ARGS[@]}"
trap - EXIT

echo ""
echo "=== VM Created ==="
echo "Talos Linux v${VERSION} VM '${VM_NAME}' is booting into maintenance mode."
echo "Connect via VNC to see the IP address it obtained, then configure it from"
echo "a workstation with talosctl, for example:"
echo "  talosctl gen config my-cluster https://<vm-ip>:6443 --install-disk /dev/vda"
echo "  talosctl apply-config --insecure --nodes <vm-ip> --file controlplane.yaml"
echo "  talosctl bootstrap --nodes <vm-ip> --endpoints <vm-ip> --talosconfig ./talosconfig"
echo "The VM boots from disk first, so the ISO is only used until Talos is installed."
