#!/usr/bin/env bash

if [ -z "$KUT_STANDALONE" ]; then
	if [ ! -f config.mak ]; then
		echo "run ./configure && make first. See ./configure -h"
		exit 2
	fi
	source config.mak
	source scripts/arch-run.bash
	source scripts/vmm.bash
fi

vmm_check_supported

function arch_run_qemu()
{
	# Allow user overrides of some config.mak variables
	mach=$MACHINE_OVERRIDE
	qemu_cpu=$TARGET_CPU_OVERRIDE
	firmware=$FIRMWARE_OVERRIDE

	: "${mach:=virt}"
	: "${qemu_cpu:=$TARGET_CPU}"
	: "${qemu_cpu:=$DEFAULT_QEMU_CPU}"
	: "${firmware:=$FIRMWARE}"
	[ "$firmware" ] && firmware="-bios $firmware"

	set_qemu_accelerator || exit $?
	[ "$ACCEL" = "kvm" ] && QEMU_ARCH=$HOST
	acc="-accel $ACCEL$ACCEL_PROPS"

	qemu=$(search_qemu_binary) || exit $?
	if [ "$mach" = 'virt' ] && ! $qemu -machine '?' | grep -q 'RISC-V VirtIO board'; then
		echo "$qemu doesn't support mach-virt ('-machine virt'). Exiting."
		exit 2
	fi
	mach="-machine $mach"

	command="$qemu -nodefaults -nographic -serial mon:stdio"
	command+=" $mach $acc $firmware -cpu $qemu_cpu "
	command="$(migration_cmd) $(timeout_cmd) $command"

	if [ "$UEFI_SHELL_RUN" = "y" ]; then
		ENVIRON_DEFAULT=n run_test_status $command "$@"
	else
		# We return the exit code via stdout, not via the QEMU return code
		run_test_status $command -kernel "$@"
	fi
}

function arch_run_kvmtool()
{
	local command

	if [ "$HOST" != "riscv32" ] && [ "$HOST" != "riscv64" ]; then
		echo "kvmtool requires KVM but the host ('$HOST') is not riscv" >&2
		exit 2
	fi

	kvmtool=$(search_kvmtool_binary) ||
		exit $?

	if [ "$ACCEL" ] && [ "$ACCEL" != "kvm" ]; then
		echo "kvmtool does not support $ACCEL" >&2
		exit 2
	fi

	if ! kvm_available; then
		echo "kvmtool requires KVM but not available on the host" >&2
		exit 2
	fi

	command="$(timeout_cmd) $kvmtool run"
	if ( [ "$HOST" = "riscv64" ] && [ "$ARCH" = "riscv32" ] ) ||
	   ( [ "$HOST" = "riscv32" ] && [ "$ARCH" = "riscv64" ] ); then
		echo "Cannot run guests with a different xlen than the host" >&2
		exit 2
	else
		run_test_status $command --kernel "$@"
	fi
}

case $(vmm_get_target) in
qemu)
	arch_run_qemu "$@"
	;;
kvmtool)
	arch_run_kvmtool "$@"
	;;
esac
