#!/bin/zsh -fuC

vm_name=Build-VM
host_nic_name=build-vm
kernel_cmdline=(
    rw quiet

    # https://make-linux-fast-again.com/
    noibrs noibpb nopti nospectre_v2 nospectre_v1 l1tf=off
    nospec_store_bypass_disable no_stf_barrier mds=off tsx=on
    tsx_async_abort=off mitigations=off
)
# shared_dir=~/kein_Backup/vm-share

#drive=( /dev/disk/by-label/Server_{Root,Var} )
#drive=( ~/kein_Backup/Server_{Root,Var}.img )
drive=( ~/kein_Backup/disk.img )
#drive=( ~/kein_Backup/debian_squeeze_powerpc_standard.qcow2 )

root_fs=$drive[1]
kernel_cmdline+=( root=UUID=$(blkid --match-tag=UUID --output=value $root_fs) )

qemu_opts=(
    -name $vm_name
    # -M mac99 -cpu G4 ## -cpu 7448 -cpu G3
    # -prom-env 'boot-device=hd:2,\grub'
    # -prom-env 'auto-boot?=false'
    -enable-kvm -cpu host,kvm=off
    -smp 6
    -m 2G #512M
    -device virtio-balloon
    -k de
    # -chardev stdio,mux=on,id=char0,signal=off
    # -mon chardev=char0,mode=readline
    # # ttyS0
    # -serial chardev:char0
    # -serial file:/tmp/$vm_name.log,logappend
    # # ttyS1
    # -serial vc
    -vga virtio -display gtk,gl=on
    -parallel none
    -nic tap,ifname=$host_nic_name,model=virtio,script=no,downscript=no
    # -nic bridge,model=virtio,helper=/bin/true,br=$host_nic_name
    # -nic user,id=net0,model=virtio-net-pci,hostname=zenbookvm
    -object rng-builtin,id=rng0
    -daemonize
)

[[ $qemu_opts == *-smp* ]] || kernel_cmdline+=( nosmp )

kernel_cmdline+=( console=ttyS0 )

die() {
    echo "$@" >&2
    exit 1
}

if (( $+root_fs ))
then
    all_files=( ${(f)"$(debugfs -f <(echo ls -p /boot) $root_fs 2>/dev/null |cut -d/ -f6)"} )
    if ! (( $+version ))
    then
        all_versions=( ${(Mnon)all_files:#vmlinuz*} )
        version=${all_versions[-1]#vmlinuz}
        (( $#version )) || die "Found no kernel image on $root_fs"
    fi

    kernel_img=$(mktemp)
    [[ -n ${(M)all_files:#initrd.img-$version} ]] \
      && initrd_img=$(mktemp)
    trap "rm '$kernel_img'${initrd_img:+ '$initrd_img'}" EXIT TERM

    debugfs -f <(print -l "dump /boot/vmlinuz-$version $kernel_img" ${initrd_img:+dump /boot/initrd.img-$version $initrd_img}) \
      $root_fs >/dev/null 2>&1 \
      || die "Failed to extract kernel and initrd"
fi

for idx in {1..$#drive}
do
    qemu_opts+=( -drive file=$drive[$idx],index=$(($idx - 1)),format=raw,media=disk,cache=writeback,if=virtio )
done

if (( $+kernel_img ))
then
    qemu_opts+=( -kernel $kernel_img -append "$kernel_cmdline console=tty0" )
    (( $+initrd_img )) && qemu_opts+=( -initrd $initrd_img )
fi

if (( ${#shared_dir:-} ))
then
    # http://wiki.qemu.org/Documentation/9psetup
    # mount -t 9p -o trans=virtio share /tmp/shared/ -oversion=9p2000.L,posixacl,cache=loose
    qemu_opts+=( -virtfs local,mount_tag=share,path=$shared_dir,security_model=none )
fi

if [[ $+host_nic_name == 1 && $(ip tuntap list) != *$host_nic_name* ]]
then
    sudo /usr/bin/ip tuntap add dev $host_nic_name mode tap user $UID
fi

# qemu doesn't like these settings, the console gets to small
unset GDK_DPI_SCALE GDK_SCALE

qemu-system-x86_64 $qemu_opts
# don't do exec! remember the TRAP
