#!/usr/local/bin/cbsd
#v10.1.2
MYARG=""
MYOPTARG="jname inter debug"
MYDESC="Start virtualbox"
ADDHELP="inter=0 to prevent any questions and to accept answers by default\n"
CBSDMODULE="virtualbox"
EXTHELP="wf_jstop_jstart"

. ${subrdir}/nc.subr
. ${system}
. ${strings}
. ${subrdir}/universe.subr
. ${subrdir}/virtualbox.subr
. ${tools}

readconf buildworld.conf
readconf jail-freebsd-default.conf
. ${subrdir}/virtualbox.subr

[ -z "${1}" ] && select_jail_by_list -s "List of offline VMs" -a "Off" -e vls -r ${sqlreplica}
. ${cbsdinit}

. ${subrdir}/fetch.subr

# MAIN for multiple jails
TRAP=""

if [ $# -gt 1 -a -z "${jname}" ]; then
	# multiple astart always non interactive
	export inter=0
	# recursive
	JLIST=$*
	for jname in ${JLIST}; do
		[ "${jname}" = "inter=0" ] && continue
		TRAP="${TRAP} /bin/rm -f ${ftmpdir}/vstart.${jname}.$$;"
		trap "${TRAP}" HUP INT ABRT BUS TERM EXIT
		/usr/local/cbsd/misc/daemonize -p ${ftmpdir}/vstart.${jname}.$$ /usr/local/bin/cbsd vstart inter=${inter} jname=${jname}
		#lets save .pid file
		sleep 1
		[ -f "${ftmpdir}/vstart.${jname}.$$" ] && cbsd_pwait --pid=$( ${CAT_CMD} ${ftmpdir}/vstart.${jname}.$$ ) --timeout=${parallel}
		trap "" HUP INT ABRT BUS TERM EXIT
		# Artificial delay to create a sequence (for order compliance)
		# todo: determine VM complete starting
		sleep 12
	done

	wait_for_fpid -a start -t ${parallel}
	err 0 "${N1_COLOR}Multiple vstart: ${N2_COLOR}done${N0_COLOR}"
fi


# MAIN
init_virtualbox

[ -z "$jname" ] && jname=$1
. ${subrdir}/rcconf.subr
[ $? -eq 1 ] && err 1 "${N1_COLOR}No such jail: ${N2_COLOR}${jname}${N0_COLOR}"
[ ${status} -eq 2 ] && err 1 "${N1_COLOR}Jail in slave mode. Please ${N2_COLOR}cbsd jswmode mode=master${N1_COLOR} first${N0_COLOR}"
[ $jid -ne 0 ] && err 1 "${N1_COLOR}Jail ${jname} already running, jid: ${N2_COLOR}${jid}${N0_COLOR}"
[ "${emulator}" != "virtualbox" ] && err 1 "${N1_COLOR}Not virtualbox mode${N0_COLOR}"
[ -z "${vm_ram}" -o -z "${vm_cpus}" -o -z "${vm_os_type}" ] && err 1 "${N1_COLOR}Parameter is mandatory: ${N2_COLOR}vm_ram, vm_cpus, vm_os_type${N0_COLOR}"


# hardcoded first disk path from SQL. Todo: mark bootable disk(s)
MDFILE=$( cbsdsqlro local SELECT dsk_path FROM ${emulator}dsk WHERE jname=\"${jname}\" AND dsk_type=\"vhd\" LIMIT 1 2>/dev/null )

case "${vm_vnc_port}" in
	0)
		vm_port=$( get-next-tcp-port start_port=5900 end_port=6900 )
		[ $? -ne 0 ] && err 1 "${N1_COLOR}no free available port in 5900-6900 range${N0_COLOR}"
		vnc_args="--vrde on --vrdeport ${vm_port} --vrdeproperty VNCPassword=cbsd"
		${ECHO} "${N1_COLOR}VRDP is enabled. VNC port: ${N2_COLOR}${vm_port}. ${N1_COLOR}VNC pass: ${N2_COLOR}cbsd${N0_COLOR}${N0_COLOR}"
		;;
	1)
		vm_port=0
		vnc_args="--vrde off"
		;;
	*)
		vm_port=${vm_vnc_port}
		vnc_args="--vrde on --vrdeport ${vm_port}"
		;;
esac

cbsdsqlrw local UPDATE virtualbox SET vm_rd_port=\"${vm_port}\" WHERE jname=\"${jname}\"

if [ "${interface}" != "auto" ]; then
	# check for interface exist
	_res=$( ${miscdir}/nics-list -s "lo" |while read _iface; do
		[ "${interface}" = "${_iface}" ] && echo "${_iface}" ] && exit 0
	done )
	[ -z "${_res}" ] && err 1 "${N1_COLOR}No such interface: ${N2_COLOR}${interface}${N0_COLOR}"
else
	auto_iface=$( /sbin/route -n get 0.0.0.0 |${AWK_CMD} '/interface/{print $2}' )
	[ -z "${auto_iface}" ] && err 1 "${N1_COLOR}Can't determine uplink interface${N0_COLOR}"
	interface="${auto_iface}"
fi


xvm_ram=$(( vm_ram / 1024 / 1024 ))
echo [debug] ${VBOX_MGMT_CMD} modifyvm ${jname} --memory ${xvm_ram} --cpus ${vm_cpus} --floppy disabled --audio none --nic1 bridged --bridgeadapter1 ${interface} --vram 16 --accelerate3d off --boot1 disk --acpi on --cableconnected1 on --usb off ${vnc_args}
${VBOX_MGMT_CMD} modifyvm ${jname} --memory ${xvm_ram} --cpus ${vm_cpus} --floppy disabled --audio none --nic1 bridged --bridgeadapter1 ${interface} --vram 16 --accelerate3d off --boot1 disk --acpi on --cableconnected1 on --usb off ${vnc_args}

if [ -n "${virtualbox_nictype}" ]; then
	${VBOX_MGMT_CMD} modifyvm ${jname} --nictype1 ${virtualbox_nictype}
else
	${VBOX_MGMT_CMD} modifyvm ${jname} --nictype1 virtio
fi

readconf vm-${vm_os_type}-${vm_os_profile}.conf
[ -z "${vm_profile}" ] && err 1 "${N1_COLOR}No such profile: ${N2_COLOR}vm-${vm_os_type}-${vm_os_profile}.conf${N0_COLOR}"
# re-read jail params and apply personal after profile
. ${subrdir}/rcconf.subr

manage_boot_by_empty_hdd
init_iso
if [ $? -eq 1 -a "${vm_boot}" = "cd" ]; then
	printf "${N1_COLOR}Continue without ${iso_img}. Hope this is ok, sleep for 5 seconds ${N0_COLOR}"
	for i in $( jot 5 ); do
		printf "."
		sleep 1
	done
	echo
fi

[ "${vm_iso_path}" != "0" ] && iso_img="${vm_iso_path}"

if [ -r "${iso_img}" ]; then
	${ECHO} "${N1_COLOR}Attaching as DVD-DRIVE: ${N2_COLOR}${iso_img}${N0_COLOR}"
	${VBOX_MGMT_CMD} storageattach ${jname} --storagectl "IDE Controller" --port 1 --device 0 --type dvddrive --medium ${iso_img}
fi

${ECHO} "${N1_COLOR}Boot from: ${N2_COLOR}${vm_boot}${N0_COLOR}"

case "${vm_boot}" in
	"hdd")
		${VBOX_MGMT_CMD} modifyvm ${jname} --boot1 disk
		${VBOX_MGMT_CMD} modifyvm ${jname} --boot2 dvd
		${VBOX_MGMT_CMD} modifyvm ${jname} --boot3 none # net
		${VBOX_MGMT_CMD} modifyvm ${jname} --boot4 none # floppy
		;;
	"cd")
		${VBOX_MGMT_CMD} modifyvm ${jname} --boot1 dvd
		${VBOX_MGMT_CMD} modifyvm ${jname} --boot2 disk
		${VBOX_MGMT_CMD} modifyvm ${jname} --boot3 none # net
		${VBOX_MGMT_CMD} modifyvm ${jname} --boot4 none # floppy
		;;
esac

echo "[debug] /usr/local/cbsd/misc/daemonize ${VBOX_HEADLESS_CMD} --startvm ${jname}"
/usr/local/cbsd/misc/daemonize ${VBOX_HEADLESS_CMD} --startvm ${jname}

exit 0
