#!/usr/bin/env bash
# Create a Windows VM for WGU Guardian browser (proctored testing)
# Usage: create-wgu-vm [windows-iso-path]
#
# If no ISO path given, scans ~/Downloads for Windows ISOs automatically.
# If none found, downloads Windows 10 22H2 from Microsoft.
# Always downloads VirtIO drivers.
#
# After creation, manage the VM:  virt-manager
# Connect to the console:        virt-viewer wgu-win

set -euo pipefail

VM_NAME="wgu-win"
RAM_MB=4096
CPUS=2
DISK_GB=64
VM_DIR="${HOME}/vms/${VM_NAME}"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

info()  { echo -e "${GREEN}==>${NC} $*"; }
warn()  { echo -e "${YELLOW}==>${NC} $*"; }
err()   { echo -e "${RED}==>${NC} $*" >&2; }

# --- Prerequisites ---
if ! command -v virsh &>/dev/null; then
  err "libvirt not found. Run:  nr"
  err "Then log out and back in (for libvirtd group)."
  exit 1
fi

if ! groups | grep -q libvirtd; then
  warn "You're not in the libvirtd group. Run:  nr"
  warn "Then log out and back in."
fi

# --- Check if VM already exists ---
if virsh dominfo "$VM_NAME" &>/dev/null; then
  info "VM '$VM_NAME' already exists."
  echo ""
  echo "  Start it:   virsh start $VM_NAME"
  echo "  Console:    virt-viewer $VM_NAME"
  echo "  Manage:     virt-manager"
  exit 0
fi

# --- Find or download Windows ISO ---
WINDOWS_ISO="${1:-}"

# If no path given, scan ~/Downloads for Windows ISOs
if [ -z "$WINDOWS_ISO" ]; then
  FOUND_ISOS=()
  while IFS= read -r -d '' f; do
    FOUND_ISOS+=("$f")
  done < <(find "${HOME}/Downloads" -maxdepth 1 -iname 'Win*.iso' -print0 2>/dev/null)

  if [ "${#FOUND_ISOS[@]}" -gt 0 ]; then
    if [ "${#FOUND_ISOS[@]}" -eq 1 ]; then
      WINDOWS_ISO="${FOUND_ISOS[0]}"
      info "Using existing ISO: $(basename "$WINDOWS_ISO")"
    else
      echo ""
      echo "Multiple Windows ISOs found in ~/Downloads:"
      for i in "${!FOUND_ISOS[@]}"; do
        echo "  [$i] $(basename "${FOUND_ISOS[$i]}")"
      done
      read -rp "Choose one [0]: " CHOICE
      CHOICE="${CHOICE:-0}"
      WINDOWS_ISO="${FOUND_ISOS[$CHOICE]}"
    fi
  fi
fi

# Still nothing? try VM_DIR cache, then download Win10
if [ -z "$WINDOWS_ISO" ]; then
  mkdir -p "$VM_DIR"
  WINDOWS_ISO="${VM_DIR}/Win10_22H2_English_x64.iso"
  if [ ! -f "$WINDOWS_ISO" ]; then
    info "No local ISO found. Downloading Windows 10 22H2 from Microsoft..."
    info "URL: https://go.microsoft.com/fwlink/?LinkID=2151180"
    warn "This is ≈6 GB — go make some coffee."
    curl -L -o "$WINDOWS_ISO" \
      "https://go.microsoft.com/fwlink/?LinkID=2151180&clcid=0x409&culture=en-us&country=us" \
      --progress-bar
  fi
fi

if [ ! -f "$WINDOWS_ISO" ]; then
  err "Windows ISO not found at: $WINDOWS_ISO"
  exit 1
fi

# --- Detect Windows version for os-variant ---
IS_NAME=$(basename "$WINDOWS_ISO")
case "$IS_NAME" in
  *1[0-9]*|*Win10*|*win10*|*WINDOWS_10*)
    OS_VARIANT="win10" ;;
  *1[12]*|*Win11*|*win11*|*WINDOWS_11*)
    OS_VARIANT="win11" ;;
  *)
    OS_VARIANT="win10" ;;
esac
info "Detected OS variant: $OS_VARIANT"

# --- Ensure VM directory exists ---
mkdir -p "$VM_DIR"

# --- VirtIO drivers ISO ---
VIRTIO_ISO="${VM_DIR}/virtio-win.iso"
if [ ! -f "$VIRTIO_ISO" ]; then
  info "Downloading VirtIO drivers..."
  curl -L -o "$VIRTIO_ISO" \
    "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso" \
    --progress-bar
fi

# --- Disk image ---
DISK_IMG="${VM_DIR}/disk.qcow2"
if [ ! -f "$DISK_IMG" ]; then
  info "Creating ${DISK_GB}G qcow2 disk image..."
  qemu-img create -f qcow2 "$DISK_IMG" "${DISK_GB}G"
fi

# --- Create VM ---
info "Creating VM '$VM_NAME' (${OS_VARIANT})..."
sudo virt-install \
  --name "$VM_NAME" \
  --ram "$RAM_MB" \
  --vcpus $CPUS,sockets=1,cores=$CPUS,threads=1 \
  --cpu host-passthrough \
  --os-variant "$OS_VARIANT" \
  --disk path="$DISK_IMG",format=qcow2,bus=virtio \
  --cdrom "$WINDOWS_ISO" \
  --disk path="$VIRTIO_ISO",device=cdrom \
  --network network=default,model=virtio \
  --graphics spice,listen=none \
  --video virtio \
  --sound ich9 \
  --channel spicevmc \
  --tpm backend.type=emulator,model=tpm-crb,version=2.0 \
  --boot uefi \
  --noautoconsole

echo ""
info "VM created! Next steps:"
echo ""
echo "  1. Connect to the VM console:"
echo "     virt-viewer $VM_NAME"
echo ""
echo "  2. During Windows install, when it can't find drives:"
echo "     Browse → Load Driver → virtio-win ISO → vioscsi → ${OS_VARIANT} → amd64 → OK"
echo "     Then select the visible disk and continue installation."
echo ""
echo "  3. After Windows installs, install Spice Guest Tools:"
echo "     Open the virtio-win ISO in Windows → run virtio-win-guest-tools.exe"
echo "     This gives you clipboard sharing, auto-resize, and better performance."
echo ""
echo "  4. Install the Guardian browser inside the VM for proctored WGU tests."
echo ""
echo "  Manage:     virt-manager"
echo "  Start:      virsh start $VM_NAME"
echo "  Stop:       virsh shutdown $VM_NAME"
echo "  Console:    virt-viewer $VM_NAME"
