#!/bin/bash

# This script automates the creation of a KVM virtual machine with VNC access,
# making it manageable via virt-manager for testing the Debian Atomic Desktop installer.

# --- Configuration Variables ---
VM_NAME="debian-atomic-test"          # Name of your virtual machine
DISK_SIZE="20G"              # Size of the virtual disk (e.g., 20G, 50G)
RAM_SIZE="4096"              # RAM allocated to the VM in MB (e.g., 4096 for 4GB)
VCPU_COUNT="2"               # Number of virtual CPUs
DISK_PATH="/var/lib/libvirt/images/${VM_NAME}.qcow2" # Path for the VM disk image
ISO_PATH="./build/debian-atomic-installer.iso" # Path to the installer ISO
NETWORK_BRIDGE="virbr0"      # Default KVM bridge network (ensure it exists or create one)
VNC_PORT="5901"              # VNC port (5901 for display 1 to avoid conflicts)

# --- Functions ---

# Function to check if a command exists
command_exists () {
    type "$1" &> /dev/null ;
}

# Function to display error and exit
error_exit () {
    echo "ERROR: $1" >&2
    exit 1
}

# Function to check if VM already exists
vm_exists() {
    virsh list --all --name | grep -q "^${VM_NAME}$"
}

# Function to destroy existing VM
destroy_vm() {
    echo "Destroying existing VM: ${VM_NAME}"
    virsh destroy "${VM_NAME}" 2>/dev/null || true
    virsh undefine "${VM_NAME}" 2>/dev/null || true
}

# --- Pre-requisites Check ---

echo "--- Checking for required packages and permissions ---"

# Check for necessary virtualization packages and libvirt service
REQUIRED_PACKAGES=("qemu-kvm" "libvirt-daemon-system" "libvirt-clients" "virt-install")
for pkg in "${REQUIRED_PACKAGES[@]}"; do
    if ! command_exists "$pkg"; then
        echo "Package or command '$pkg' not found on the host system."
        echo "For Debian/Ubuntu-based systems:"
        echo "  sudo apt update && sudo apt install -y $pkg"
        echo "For Fedora/CentOS/RHEL-based systems (including Bazzite):"
        echo "  sudo dnf install -y $pkg"
        echo "  (For immutable distros like Bazzite, use 'sudo rpm-ostree install $pkg')"
        error_exit "Missing required package/command on the host system."
    fi
done

# Check if current user is in libvirt group
if ! groups | grep -q "libvirt"; then
    echo "Current user is not in 'libvirt' group. You must be in this group to manage VMs."
    echo "Please add yourself and then log out and log back in for changes to take effect:"
    echo "  sudo usermod -aG libvirt $USER"
    error_exit "User not in libvirt group."
fi

# Check if libvirtd service is running
if ! systemctl is-active --quiet libvirtd; then
    echo "The 'libvirtd' service is not running. KVM VMs cannot be managed without it."
    echo "Please start it: sudo systemctl start libvirtd"
    echo "And enable it to start on boot: sudo systemctl enable libvirtd"
    error_exit "libvirtd service not active."
fi

# Check if the ISO path is valid
if [ ! -f "$ISO_PATH" ]; then
    error_exit "ISO file not found at '$ISO_PATH'. Please build the installer first with 'just build-iso'."
fi

# Check if the disk image path directory exists
DISK_DIR=$(dirname "$DISK_PATH")
if [ ! -d "$DISK_DIR" ]; then
    echo "Creating disk image directory: $DISK_DIR"
    sudo mkdir -p "$DISK_DIR" || error_exit "Failed to create disk image directory."
fi

# --- Main Script ---

echo "--- Starting VM Creation Process ---"

# Check if VM already exists
if vm_exists; then
    echo "VM '${VM_NAME}' already exists."
    read -p "Do you want to destroy the existing VM and recreate it? (y/N): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        destroy_vm
    else
        echo "Using existing VM. You can start it with: virsh start ${VM_NAME}"
        exit 0
    fi
fi

# 1. Create the virtual disk image
if [ -f "$DISK_PATH" ]; then
    echo "Warning: Disk image '$DISK_PATH' already exists."
    read -p "Do you want to delete the existing disk image and recreate it? (y/N): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        echo "Deleting existing disk image..."
        sudo rm -f "$DISK_PATH" || error_exit "Failed to delete existing disk image."
        echo "Creating new disk image: $DISK_PATH (${DISK_SIZE})"
        sudo qemu-img create -f qcow2 "$DISK_PATH" "$DISK_SIZE" || error_exit "Failed to create disk image."
    else
        echo "Using existing disk image."
    fi
else
    echo "Creating disk image: $DISK_PATH (${DISK_SIZE})"
    sudo qemu-img create -f qcow2 "$DISK_PATH" "$DISK_SIZE" || error_exit "Failed to create disk image."
fi

# Ensure correct permissions for the disk image
sudo chown libvirt-qemu:kvm "$DISK_PATH" || error_exit "Failed to set permissions on disk image."
sudo chmod 660 "$DISK_PATH" || error_exit "Failed to set permissions on disk image."

# 2. Create the VM using virt-install
echo "Creating VM '$VM_NAME' with virt-install..."
echo "  RAM: ${RAM_SIZE}MB"
echo "  VCPUs: ${VCPU_COUNT}"
echo "  Disk: ${DISK_PATH}"
echo "  ISO: ${ISO_PATH}"
echo "  Network: ${NETWORK_BRIDGE}"
echo "  VNC Port: ${VNC_PORT}"

virt-install \
    --name "${VM_NAME}" \
    --memory "${RAM_SIZE}" \
    --vcpus "${VCPU_COUNT}" \
    --disk path="${DISK_PATH}",format=qcow2 \
    --cdrom "${ISO_PATH}" \
    --network bridge="${NETWORK_BRIDGE}",model=virtio \
    --graphics vnc,listen=0.0.0.0,port="${VNC_PORT}" \
    --os-type linux \
    --os-variant debian12 \
    --noautoconsole \
    --boot cdrom \
    --virt-type kvm \
    --import \
    --wait 0 || error_exit "Failed to create VM with virt-install."

echo "VM '$VM_NAME' created successfully!"

# --- Post-creation Instructions ---

echo "--- Next Steps ---"
echo "1. The VM '${VM_NAME}' has been created and should be starting."
echo "2. To connect to the VM using virt-manager:"
echo "   If virt-manager is a Flatpak (like on Bazzite):"
echo "     /usr/bin/flatpak run --branch=stable --arch=x86_64 --command=virt-manager org.virt_manager.virt-manager"
echo "   Otherwise (native installation):"
echo "     virt-manager"
echo "   In virt-manager, you should see '${VM_NAME}' VM. Double-click it to open the console."
echo "3. To connect directly via a VNC client (e.g., Remmina, TightVNC Viewer), use:"
echo "   VNC Server: YourHostIP:${VNC_PORT}"
echo "   (Replace 'YourHostIP' with the IP address of the machine running the VM)"
echo "4. Test the Debian Atomic Desktop installer in the VM."
echo "5. After testing, you can destroy the VM with:"
echo "   virsh destroy ${VM_NAME}"
echo "   virsh undefine ${VM_NAME}"
echo ""
echo "Script finished." 