#!/usr/bin/env bash

_error() {

        $ECHOCMD "${RED}$1, sortie... ${NORMAL}"
        exit 1
}
_warning() {

        $ECHOCMD "${RED}Attention ..., $1${NORMAL}"
}

_info() {

        $ECHOCMD "${YELLOW}${1}${NORMAL}"
}

_success() {

        $ECHOCMD "${GREEN}${1}${NORMAL}"
}

check_zenity_bin() {
[[ $ZENITY_BIN == '' ]] && INSTALLED_ZENITY="no"
}

check_args() {
if [[ $# -lt 1 ]]; then
	if [[ $INSTALLED_ZENITY != "no" ]]; then
		_warning "The only argument needed seems to missing"
                _warning "What is the VM you want to start ?"
		_warning "A graphical window will open in 2 secs"
		sleep 2
		_FULLPATHNAME=$(${ZENITY_BIN} --file-selection --title="Choose a VM" --filename=${_VM_FOLDER}/ --directory)
		_NAME=${_FULLPATHNAME##*/}
	else
		ls --color=auto ${_VM_FOLDER}
		_warning "The only argument needed seems to missing"
		_warning "What is the VM you want to start ?"
		read _NAME
		_FULLPATHNAME=${_VM_FOLDER}/${_NAME}
	fi
fi
}

check_var_file() {
if [[ ! -f ${_FULLPATHNAME}/${_NAME}.var ]]; then
        _error "VM configuration file does not exist, please use configvm script to create it"
else
	source ${_FULLPATHNAME}/${_NAME}.var
	_success "The disk $HDD1_NAME will be used for the VM"
	_success "The VM will boot in $BIOS_TYPE_INFO"
	_success "The iso image $ISO_FILE is attached to the VM"
fi
}

check_hdd1_file() {
[[ ! -f $HDD1_NAME ]] &&  _error "The VM hard disk does not exist, please use the configvm script to create it"
}

check_hdd2() {
if [[ -n $HDD2_NAME ]]
	then
		ADD_HDD2="-drive file=${HDD2_NAME},if=${HDD2_CONTROLLER_TYPE,,}"
		[[ ! -f $HDD2_NAME ]] &&  _error "The second hard disk of the VM does not exist"
fi
}

check_hdd3() {
if [[ -n $HDD3_NAME ]]
        then
		ADD_HDD3="-drive file=${HDD3_NAME},if=${HDD3_CONTROLLER_TYPE,,}"
		[[ ! -f $HDD3_NAME ]] &&  _error "The third hard disk of the VM does not exist"
fi
}

uefi_bioscmdline() {
case $BIOS_TYPE_INFO in
	uefi|UEFI)
		_UEFI_CODE_CMDLINE="-drive if=pflash,format=raw,readonly=on,file=/usr/share/ovmf/x64/OVMF_CODE.fd"
                _UEFI_VAR_CMDLINE="-drive if=pflash,format=raw,file=$OVMF_VAR_DISK_INFO"
	;;
	*)
		_UEFI_CMDLINE=""
	;;
esac
}

iso_disk_cmdline() {
case $ISO_FILE in
        no|NO|none|NONE|'')
                _ISO_CMDLINE=""
        ;;
        *)
                _ISO_CMDLINE="-drive file=$ISO_FILE,media=cdrom,if=ide"
        ;;
esac
}

sndhw_cmdline() {
case $SOUND_CARD_TYPE in
        none|NONE|no)
                _SNDHW_CMDLINE=""
        ;;
        ac97)
                _SNDHW_CMDLINE="-device AC97"
        ;;
	*)
		_SNDHW_CMDLINE="-soundhw $SOUND_CARD_TYPE"
	;;
esac
}

vga_cmdline() {
case $VGA_HARDWARE_TYPE in
        virtio|Virtio|VIRTIO)
                _VGA_CMDLINE="-device virtio-vga,max_hostmem=$(( ${VGA_MEMORY_SIZE/[A-Z]*/} * 1024 * 1024 ))"
        ;;
        qxl|Qxl|QXL)
                _VGA_CMDLINE="-device qxl-vga,vgamem_mb=${VGA_MEMORY_SIZE/[A-Z]*/}"
        ;;
        cirrus|Cirrus|CIRRUS)
                _VGA_CMDLINE="-device cirrus-vga,vgamem_mb=${VGA_MEMORY_SIZE/[A-Z]*/}"
        ;;
        *)
                _VGA_CMDLINE="-vga $VGA_HARDWARE_TYPE"
	;;
esac
}

display_cmdline() {
case $VGA_DISPLAY_TYPE in
        vnc|VNC)
                _DISPLAY_CMDLINE="-$VGA_DISPLAY_TYPE $REMOTE_PORT -k $VNC_LAYOUT $DISPLAY_OPTS"
        ;;
        spice)
                _DISPLAY_CMDLINE="-$VGA_DISPLAY_TYPE port=$REMOTE_PORT,$DISPLAY_OPTS"
        ;;
	gtk)
		if [[ $LOCAL_FULLSCREEN == yes ]]; then
			_DISPLAY_CMDLINE="-display $VGA_DISPLAY_TYPE -full-screen"
		else
			_DISPLAY_CMDLINE="-display $VGA_DISPLAY_TYPE"
		fi
	;;
	egl-headless)
		_DISPLAY_CMDLINE="-display $VGA_DISPLAY_TYPE -spice port=$REMOTE_PORT,$DISPLAY_OPTS"
	;;
	*)
		_DISPLAY_CMDLINE="-display $VGA_DISPLAY_TYPE"
	;;
esac
}


qemu_cmdline() {

_info "Command line summary :"

cat << EOF

-M q35 -m $SYSTEM_MEMORY_SIZE -cpu $CPU_TYPE -smp cores=$NUMBER_OF_CORES
-device $NETWORK_HARDWARE_TYPE,netdev=net0 -netdev $NETWORK_TYPE,id=net0
-device virtio-balloon
${_UEFI_CODE_CMDLINE}
${_UEFI_VAR_CMDLINE}
-drive file=$HDD1_NAME,if=$HDD1_CONTROLLER_TYPE
$HDD1_CONTROLLER_EXTRA
${ADD_HDD2}
${ADD_HDD3}
${_ISO_CMDLINE}
-boot menu=on
${_VGA_CMDLINE}
${_SNDHW_CMDLINE}
-nodefaults
${_DISPLAY_CMDLINE}
-usb
-object rng-random,id=rng0
-device virtio-rng,id=rng0
-monitor $MONITOR

EOF

$QEMU_BIN -enable-kvm -M q35 -m $SYSTEM_MEMORY_SIZE -cpu $CPU_TYPE -smp cores=$NUMBER_OF_CORES \
          -device $NETWORK_HARDWARE_TYPE,netdev=net0 -netdev $NETWORK_TYPE,id=net0 \
          -device virtio-balloon \
          ${_UEFI_CODE_CMDLINE} ${_UEFI_VAR_CMDLINE} \
          -drive file=${HDD1_NAME},if=${HDD1_CONTROLLER_TYPE,,} \
          $HDD1_CONTROLLER_EXTRA \
          ${ADD_HDD2} \
          ${ADD_HDD3} \
          ${_ISO_CMDLINE} \
          -boot menu=on  \
          ${_VGA_CMDLINE} \
          ${_SNDHW_CMDLINE} \
          -nodefaults \
          ${_DISPLAY_CMDLINE} \
          -usb \
          -object rng-random,id=rng0 \
          -device virtio-rng,id=rng0 \
          -monitor $MONITOR
}

main() {
check_zenity_bin
check_args "$@"
check_var_file
check_hdd1_file
check_hdd2
check_hdd3
uefi_bioscmdline
iso_disk_cmdline
sndhw_cmdline
vga_cmdline
display_cmdline
qemu_cmdline
}

RED='\033[31m'
NORMAL='\033[0m'
YELLOW='\033[33m'
GREEN='\033[32m'

QEMU_BIN=$(which qemu-system-x86_64)
ECHOBIN=$(which echo)
ZENITY_BIN=$(which zenity)

ECHOCMD="$ECHOBIN -e"

_NAME=$1
_VM_FOLDER=$HOME/VM-qemu
_FULLPATHNAME=${_VM_FOLDER}/${_NAME}
main "$@"
