#!/usr/bin/env bash
# run-qemu-desktop.sh — arranca la imagen KDE en QEMU (virtio-gpu + software GL) de forma REPRODUCIBLE.
# Antes era un comando ad-hoc. Por defecto headless (DISPLAY=none) para diagnóstico por serial sin
# interferir con la sesión mirada del laptop; DISP=gtk para ver la ventana (necesita DISPLAY=:0 Xwayland,
# y cada restart de mirada mata la ventana).
#
#   scripts/kde/run-qemu-desktop.sh              # headless, serial → work/qemu-desktop-serial.log
#   DISP=gtk scripts/kde/run-qemu-desktop.sh     # ventana gráfica (virtio-gpu por gtk)
#   TIMEOUT=90 scripts/kde/run-qemu-desktop.sh   # mata QEMU a los 90s (diagnóstico automático)
set -euo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"

IMG="${IMG:-work/hammer-kde-qemu.img}"
SERIAL="${SERIAL:-work/qemu-desktop-serial.log}"
OVMF_CODE="${OVMF_CODE:-/usr/share/edk2/x64/OVMF_CODE.4m.fd}"
OVMF_VARS_SRC="${OVMF_VARS_SRC:-/usr/share/edk2/x64/OVMF_VARS.4m.fd}"
VARS="${VARS:-work/qemu-desktop-OVMF_VARS.fd}"
DISP="${DISP:-none}"
MEM="${MEM:-4G}"
SMP="${SMP:-4}"

[ -r "$IMG" ] || { echo "falta $IMG — corré scripts/kde/qemu-desktop-image.sh" >&2; exit 1; }
[ -r "$OVMF_CODE" ] || { echo "falta OVMF_CODE ($OVMF_CODE)" >&2; exit 1; }
# copia escribible de las VARS (pflash necesita rw; la del sistema es read-only)
[ -r "$VARS" ] || cp "$OVMF_VARS_SRC" "$VARS"

case "$DISP" in
  gtk) DISPLAY_ARGS=(-display gtk -device virtio-gpu-pci) ;;
  none) DISPLAY_ARGS=(-display none -device virtio-gpu-pci) ;;
  *) DISPLAY_ARGS=(-display "$DISP" -device virtio-gpu-pci) ;;
esac

# serial nuevo cada corrida (el diagnóstico depende de que no se mezcle con boots viejos)
: > "$SERIAL"

QEMU_ARGS=(
  -machine q35 -accel kvm -cpu host
  -m "$MEM" -smp "$SMP"
  -vga none    # virtio-gpu-pci (abajo) es el ÚNICO display: sin esto QEMU añade una VGA estándar por
               # defecto y OVMF pinta el GOP ahí ⇒ simpledrm (card1) muestra el framebuffer EFI y kwin
               # pinta en virtio-gpu (card0, otro device que no se ve) ⇒ pantalla congelada en TianoCore.
               # Con -vga none, OVMF usa virtio-gpu ⇒ virtio-gpu-DRM expulsa simpledrm ⇒ un solo output.
  -drive if=pflash,format=raw,unit=0,file="$OVMF_CODE",readonly=on
  -drive if=pflash,format=raw,unit=1,file="$VARS"
  -drive file="$IMG",format=raw,if=virtio
  "${DISPLAY_ARGS[@]}"
  -serial "file:$SERIAL"
  -monitor "unix:${MON:-work/qemu-monitor.sock},server,nowait"
  -no-reboot
)

# AUDIO=1 (default): darle a la VM una tarjeta de sonido EMULADA. No es para oír nada —el backend es
# `none`, que descarta las muestras— sino para que HAYA UN DISPOSITIVO QUE ENUMERAR.
#
# Sin esto, `wpctl status` sale con «Devices:» vacío y un único sink `auto_null`, y ese resultado es
# AMBIGUO: se lee igual si wireplumber funciona sobre una VM sin hardware que si wireplumber no
# funciona. Con una ich9-intel-hda emulada, el árbol de /sys/class/sound existe y la respuesta
# distingue las dos cosas. AUDIO=0 para volver al caso sin tarjeta.
if [ "${AUDIO:-1}" = 1 ]; then
  QEMU_ARGS+=(-audiodev none,id=snd0 -device ich9-intel-hda -device hda-duplex,audiodev=snd0)
fi

# NET=none (default): SIN tarjeta de red. No es sólo ahorro — QEMU añade una e1000 por defecto, y OVMF
# la usa para crear entradas de arranque PXE/HTTP (IPv4 e IPv6). Cuando la entrada de disco que OVMF
# tenía cacheada en sus VARS deja de coincidir —y basta AGREGAR UN DISPOSITIVO PCI, como la tarjeta de
# sonido de arriba, para que las rutas se corran— la firmware cae al orden por defecto y se pasa un
# par de minutos en timeouts de PXE antes de llegar al disco. Con un TIMEOUT corto eso se ve como
# «la VM no arrancó», y el serial sólo muestra `PXE-E16: No valid offer received`. Pasó de verdad.
# Este escritorio no necesita red; `NET=user` si algún día hace falta.
if [ "${NET:-none}" = none ]; then
  QEMU_ARGS+=(-nic none)
fi

echo "==> QEMU (DISP=$DISP, serial=$SERIAL)"
echo "    imagen: $IMG"
if [ -n "${TIMEOUT:-}" ]; then
  echo "    TIMEOUT=${TIMEOUT}s (auto-kill)"
  exec timeout --signal=KILL "${TIMEOUT}" qemu-system-x86_64 "${QEMU_ARGS[@]}"
else
  exec qemu-system-x86_64 "${QEMU_ARGS[@]}"
fi
