#!/usr/bin/env bash
set -euo pipefail
ROOT=$(git rev-parse --show-toplevel)

VM_NAME="talos-vm"
VCPUS="6"
RAM_MB="16384"
DISK_GB="100"
NETWORK=talos
CONNECTION="qemu:///system"

function define_network() {
	config_file=$(mktemp)
	cat > ${config_file} << EOF
<network>
	<name>${NETWORK}</name>
	<bridge name="talos0" stp="on" delay="0"/>
	<forward mode='nat'>
		<nat/>
	</forward>
	<ip address="192.168.1.1" netmask="255.255.255.0">
		<dhcp>
			<range start="192.168.1.2" end="192.168.1.254"/>
			<bootp file='http://192.168.1.1:8000/ipxe.pxe'/>
		</dhcp>
	</ip>
</network>
EOF

	function cleanup() {
		rm ${config_file}
	}
	trap cleanup EXIT

	if [[ $(virsh --connect="${CONNECTION}" net-list --all | grep -c "${NETWORK}") == "0" ]]; then
		virsh --connect="${CONNECTION}" net-define "${config_file}"
		virsh --connect="${CONNECTION}" net-start "${NETWORK}"
		virsh --connect="${CONNECTION}" net-autostart "${NETWORK}"
	fi

	trap - EXIT
	cleanup
}


function create() {
	define_network

	if [[ $(virsh --connect="${CONNECTION}" list --all | grep -c "${VM_NAME}") == "0" ]]; then
		virt-install --connect="${CONNECTION}" --name="${VM_NAME}" --vcpus="${VCPUS}" --memory="${RAM_MB}" \
			--os-variant="linux2022" \
			--disk="size=${DISK_GB}" \
			--pxe \
			--sysinfo system.serial=${VM_NAME} \
			--network network="${NETWORK}"
	else
		echo -n "VM already exists, start it with:
	${0} start
"
		exit -1
	fi
}

function start() {
	if [[ $(virsh --connect="${CONNECTION}" list --all | grep -c "${VM_NAME}") > "0" ]]; then
		virsh --connect="${CONNECTION}" start ${VM_NAME}
		virt-viewer --connect="${CONNECTION}" ${VM_NAME}
	else
		echo -n "VM doest not exists yet, create it with:
	${0} create
"
		exit -1
	fi
}

function connect() {
	if [[ $(virsh --connect="${CONNECTION}" list | grep -c "${VM_NAME}") > "0" ]]; then
		virt-viewer --connect="${CONNECTION}" ${VM_NAME}
	else
		echo "VM is not running"
		exit -1
	fi
}

function stop() {
	if [[ $(virsh --connect="${CONNECTION}" list | grep -c "${VM_NAME}") > "0" ]]; then
		virsh --connect="${CONNECTION}" shutdown ${VM_NAME}
		WAIT=240
		for i in $(seq 0 1 ${WAIT}); do
			echo -en "\rWaiting for VM to shutdown... (${i}/${WAIT})"

			if [[ $(virsh --connect="${CONNECTION}" list | grep -c "${VM_NAME}") == "0" ]]; then
				echo -e "\nVM successfully shutdown"
				exit
			fi

			sleep 1
		done

		echo -e "\nDestroying VM"
		virsh --connect="${CONNECTION}" destroy ${VM_NAME}
	else
		echo "VM is not running"
		exit -1
	fi
}

function delete() {
	if [[ $(virsh --connect="${CONNECTION}" list --all | grep -c "${VM_NAME}") > "0" ]]; then
		if [[ $(virsh --connect="${CONNECTION}" list | grep -c "${VM_NAME}") > "0" ]]; then
			virsh --connect="${CONNECTION}" destroy "${VM_NAME}"
		fi
		virsh --connect="${CONNECTION}" undefine "${VM_NAME}" --remove-all-storage
	fi

	if [[ $(virsh --connect="${CONNECTION}" net-list --all | grep -c "${NETWORK}") > "0" ]]; then
		if [[ $(virsh --connect="${CONNECTION}" list | grep -c "${VM_NAME}") > "0" ]]; then
			virsh --connect="${CONNECTION}" net-destroy "${NETWORK}"
		fi
		virsh --connect="${CONNECTION}" net-undefine "${NETWORK}"
	fi
}

function help() {
	echo -n "Available commands:
	start
	stop
	remove
	connect
"
}

COMMAND=${1:-}
case ${COMMAND} in
	create)
		create			Create the vm and perform first install
		;;
	start)
		start			Start the vm
		;;
	stop)
		stop			Stop the vm
		;;
	delete)
		delete			Delete the vm
		;;
	connect)
		connect			Connect to an already running vm
		;;
	*)
		help
		;;
esac
