#!/bin/sh

set -e

# This logic to detect virtualization technology is inspired
# from systemd-detect-virt (detect_vm() in src/basic/virt.c)
detect_virt_dmi_entry() {
    local entry=$1
    if [ ! -e "$entry" ]; then
	return
    fi
    case "$(cat $entry)" in
	KVM*)       echo "kvm";;
	QEMU*)      echo "qemu";;
	VMware*)    echo "vmware";;
	VMW*)       echo "vmware";;
	innotek*)   echo "oracle";;
	Xen*)       echo "xen";;
	Bochs*)     echo "bochs";;
	Parallels*) echo "parallels";;
	BHYVE*)     echo "bhyve";;
    esac
}

detect_virt_dmi() {
    local path
    local result
    for path in /sys/class/dmi/id/product_name \
	        /sys/class/dmi/id/sys_vendor \
		/sys/class/dmi/id/board_vendor \
		/sys/class/dmi/id/bios_vendor; do
	result=$(detect_virt_dmi_entry $path)
	if [ -n "$result" ]; then
	    echo "$result"
	    return
	fi
    done
}

log() {
    logger -t hw-detect "$@"
}

mount_sys_and_proc() {
    local to_umount=""
    if [ ! -e /target/sys/class ]; then
	mount -t sysfs none /target/sys
	to_umount="/target/sys"
    fi
    if [ ! -e /target/proc/sys ]; then
	mount -t proc none /target/proc
	to_umount="$to_umount /target/proc"
    fi
    echo "$to_umount"
}

detect_virt() {
    # First try to use systemd-detect-virt, it knows a lot more.
    if [ -x /target/usr/bin/systemd-detect-virt ]; then
	to_umount=$(mount_sys_and_proc)
	virt=$(chroot /target systemd-detect-virt || true)
	for path in $to_umount; do
	    umount $path || true
	done
	log "detected virtualization '$virt' (with systemd-detect-virt)"
    fi
    # Otherwise, rely on DMI information
    if [ -z "$virt" ]; then
	virt=$(detect_virt_dmi)
	log "detected virtualization '$virt' (with DMI data)"
    fi
    echo -n "$virt"
}

detect_desktop() {
   if chroot /target dpkg-query -W -f='${db:Status-Status}\n' \
	    xserver-xorg-core task-desktop | grep -q ^installed; then
	return 0
   fi
   return 1
}

disable_modules_loading() {
	if [ ! -d /target/etc/modprobe.d ]; then
	    return
	fi
	cat >/target/etc/modprobe.d/di-hw-detect-blacklist.conf <<EOF
# Disable loading of all modules during initial installation
# (temporary change made by debian-installer $0)
alias * all-modules
blacklist all-modules
EOF
}

enable_modules_loading() {
	rm -f /target/etc/modprobe.d/di-hw-detect-blacklist.conf

	# Now regenerate the initrd without the blacklist that got
	# embedded and that we don't want
	in-target update-initramfs -u -k all || true
}


case "$(detect_virt)" in
    vmware)
	if detect_desktop; then
	    apt-install --with-recommends open-vm-tools-desktop || true
	else
	    apt-install --with-recommends open-vm-tools || true
	fi
	;;
    oracle)
	# XXX: Virtualbox uses DKMS, which will load modules that
	# will break d-i's X server, so disable module loading for now
	# see #931017 for the dkms bug report
	disable_modules_loading
	if detect_desktop; then
	    apt-install --with-recommends virtualbox-guest-x11 || true
	else
	    apt-install --with-recommends virtualbox-guest-utils || true
	fi
	enable_modules_loading
	;;
    microsoft)
	apt-install --with-recommends hyperv-daemons || true
	;;
    kvm|qemu)
	apt-install --with-recommends qemu-guest-agent || true
	if detect_desktop; then
	    apt-install --with-recommends spice-vdagent || true
	fi
	;;
    xen)
	# XXX: do we need anything for Xen?
	;;
esac

# Might have been queued early on, expecting either 0 or 1 by construction:
if [ -s /tmp/microcode.list ]; then
    pkg=$(cat /tmp/microcode.list)
    log "installing $pkg"
    apt-install --with-recommends $pkg || true
fi
