#!/bin/sh
set -eu
[ -r conf ] && . ./conf
: "${BHYVE:=/usr/sbin/bhyve}"
: "${BHYVELOAD:=/usr/sbin/bhyveload}"
: "${OPTS:=}"

# bhyve@<name>@<mem>@<cpus>@<bridge>@<bootmethod>
myifs="${IFS}"
IFS="@"
i=0
for f in ${PWD}; do
	case ${i} in
	1) name=${f} ;;
	2) mem=${f} ;;
	3) cpus=${f} ;;
	4) bridge=${f} ;;
	5) bootmethod=${f} ;;
	6) exit 1 ;;
	esac
	i=$((i + 1))
done
IFS="${myifs}"

: "${mem:=512m}"
: "${cpus:=1}"
: "${bridge:=bhyve0}"
: "${bootmethod:=uefi}"

kldload -qn if_tuntap nmdm vmm || true
kldload -qn if_tap || true
if ! ifconfig ${bridge} >/dev/null 2>&1; then
	ifconfig bridge create name ${bridge} group runit-managed up
fi
sysctl net.link.tap.up_on_open=1 >/dev/null

slots="-s 0,hostbridge"
[ -r "cdrom" ] && slots="${slots} -s 1,ahci-cd,$(readlink cdrom)"
for i in $(seq 0 15); do
	if [ -r "disk${i}" ]; then
		disk="$(readlink "disk${i}")"
		slots="${slots} -s $((i + 2)),virtio-blk,${disk},nocache,direct"
	fi
done

intf=$(ifconfig tap create group runit-managed)
echo "${intf}" >supervise/network-interfaces
ifconfig "${bridge}" addm "${intf}"
slots="${slots} -s 18,virtio-net,${intf}"
slots="${slots} -s 31,lpc"

case "${bootmethod}" in
uefi) bootarg="-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI.fd" ;;
csm) bootarg="-l bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI_CSM.fd" ;;
bhyveload)
	bootarg=""
	${BHYVELOAD} -c "/dev/nmdm${name}A" \
		-m "${mem}" \
		-d "$(readlink "disk0")" \
		"${name}"
	;;

*)
	echo "unsupported boot method: ${bootmethod}"
	exit 1
	;;
esac

# shellcheck disable=SC2086
exec ${BHYVE} -A -H -P \
	-c ${cpus} \
	-m ${mem} \
	${slots} \
	-l "com1,/dev/nmdm${name}A" \
	${bootarg} \
	${OPTS} \
	"${name}"
