#!/usr/local/bin/cbsd
#v11.1.12
MYARG=""
MYOPTARG="mode"
CBSDMODULE="xen"
MYDESC="Ncurses based Xen guest creation wizard"
EXTHELP="wf_xcreate"
ADDHELP="\
  mode=full for all atributes\n\
"
# TODO: bios='ovmf' for UEFI
. ${subrdir}/nc.subr
. ${cbsdinit}

. ${subrdir}/xen.subr
# preliminary reading of some pre-defined constants for tui messages
readconf xen-default-default.conf

. ${subrdir}/settings-tui.subr
. ${subrdir}/settings-tui-virtual.subr
. ${subrdir}/settings-tui-xen.subr
. ${dialog}

extra_default_item=

gen_newjail_conf()
{
	local _i _required _mytest _ret

	_required="jname host_hostname ip4_addr ver arch imgsize"

	if [ ${is_cloud} -eq 1 ]; then
		_required="${_required} cloud_init_options"
	fi

	msg_ok="ok"

	for _i in ${_required}; do
		eval _mytest=\$$_i
		if [ -z "${_mytest}" ]; then
			f_dialog_msgbox "${_i} must be filled" "Error"
			extra_default_item="${_i}"
			return 0
		fi
	done

	unset extra_default_item

	# adjust default sectorize
	if [ -z "${sectorsize}" ]; then
		sectorsize="${default_sectorsize}"
		[ -z "${sectorsize}" ] && sectorsize="4096"
	fi

	#check for ip if oninterface
	if [ "${interface}" != "0" -a -n "${ip4_addr}" ]; then
		checkip ip=${ip4_addr} check=1 2>/dev/null
		case $? in
			2)
				msg_yes="ok"
				msg_no="not ok"
				f_dialog_noyes "It seems like ${ip4_addr} address already used on several devices on the LAN\nYou can found MAC address by \"arp -an\" command.\n If you believe that it's ok, choose 'ok' to continue or 'not ok' for another IP address" "WARNING"
				case $? in
					0)
						;;
					*)
						return 0
						;;
				esac
		esac
	fi

	if [ "${spice_enabled}" = "1" ]; then
		spice_default=1
	else
		spice_default=0
	fi

	gen_jconf
	ERR=$?

	[ ${ERR} -eq 0 ] || err 1 "${N1_COLOR}bad conf${N0_COLOR}"
	err 0 ${A}
}

dialog_menu_main()
{
	local title=" ${product} v${myversion} "
	local btitle="${DIALOG_BACKTITLE}"
	local prompt="Use menu for construct jail create config file"

	local defaultitem= # Calculated below

	local hline=
	local mark
	local i _mytest

	f_dialog_default_fetch defaultitem

	# checkbox mark
	for i in astart; do
		eval _mytest=\$$i
		if [ "${_mytest}" = "1" ]; then
			export ${i}_mark="X"
		else
			export ${i}_mark=" "
		fi
	done

	item_let="A"
	item_num="0"
	local menu_list=""

	menu_list="${menu_list}	'${item_let} vm_os_type'	'$(curval vm_os_type)'		'Guest OS type'"
	inc_menu_index item_let
	menu_list="${menu_list}	'${item_let} vm_os_profile'	'$(curval vm_os_profile)'	'Guest OS profile'"
	inc_menu_index item_let

	if [ "${from_jail}" = "1" -a "${xen_profile}" != "FreeBSD-bsdinstall-jail" ]; then
		menu_list="${menu_list}	'${item_let} jprofile'	'$(curval jprofile)'		'Select jail profile for jcreate'"
	fi

	local vm_package_num=$( cbsdsqlro local SELECT COUNT\(name\) FROM vmpackages )

	if ! is_number ${vm_package_num}; then
		if [ ${vm_package_num} -gt 0 ]; then
			menu_list="${menu_list}	'${item_let} vm_package'	'$(curval vm_package)'		'Package group name'"
			inc_menu_index item_let
		fi
	fi

	menu_list="${menu_list}	'${item_let} jname'		'$(curval jname)'		'A short jail name'"
	inc_menu_index item_let
	menu_list="${menu_list}	'${item_let} host_hostname'	'$(curval host_hostname)'	'Full (FQDN) jail hostname'"
	inc_menu_index item_let
	menu_list="${menu_list}	'${item_let} imgsize'		'$(curval imgsize)'		'reserved (expand) X size for free space'"
	inc_menu_index item_let

	if [ ${is_cloud} -eq 0 ]; then
		# moved to cloud-init helper for cloud host
		menu_list="${menu_list}	'${item_let} ip4_addr'	'$(curval ip4_addr)'	'${ip4_addr_msg}'"
		inc_menu_index item_let
	fi

	menu_list="${menu_list}	'${item_let} vm_ram'		'$(curval vm_ram)'		'RAM'"
	inc_menu_index item_let
	menu_list="${menu_list}	'${item_let} vm_cpus'		'$(curval vm_cpus)'		'CPUs number'"
	inc_menu_index item_let

	if [ ${is_cloud} -eq 0 ]; then
		# not for cloud
		menu_list="${menu_list}	'${item_let} vm_iso_path'	'$(curval vm_iso_path)'	'ISO Path for CD-ROM'"
		inc_menu_index item_let
	fi

	menu_list="${menu_list}	'${item_let} astart'		'[${astart_mark}]'		'Autostart with system'"
	inc_menu_index item_let
	menu_list="${menu_list}	'${item_let} interface'		'$(curval interface)'		'Interface selection and aliasing mode'"

	# todo
	inc_menu_index item_let
	menu_list="${menu_list} '${item_let} vm_vnc_port'	'$(curval vm_vnc_port)'		'VNC port'"

	if [ ${is_cloud} -eq 1 ]; then
		menu_list="${menu_list} '${item_let} cloud_init_options'        '$(curval cloud_init_options)'  'cloud-init settings'"
		inc_menu_index item_let
	fi

	menu_list="${menu_list} '${item_let} debug_engine'		'$(curval debug_engine)'	'Run in debugger?'"
	inc_menu_index item_let

	if [ "${zfsfeat}" = "1" ]; then
		menu_list="${menu_list} '-'			'-'				''"
		inc_menu_index item_num
		menu_list="${menu_list} '${item_num} imgtype'		'$(curval imgtype)'	'ZVOL or MD disk type'"
		inc_menu_index item_num
		menu_list="${menu_list} '${item_num} zfs_snapsrc'	'$(curval zfs_snapsrc)'	'Create XEN from ZFS snapshot'"
	fi

	inc_menu_index item_num
	menu_list="${menu_list} '${item_num} xen_vnc_options'	'VNC options >>'		'VNC opt: bind:${xen_vnc_tcp_bind} vnc_password:XXX'"
	inc_menu_index item_num
	menu_list="${menu_list} '${item_num} xen_spice_options'	'SPICE options >>'		'SPICE opt: bind:${xen_spice_tcp_bind} spice_password:XXX'"
	inc_menu_index item_num
	menu_list="${menu_list} '${item_num} xen_audio_options'	'Audio options >>'		'Audio opt: ${soundhw}'"
	inc_menu_index item_num

	menu_list="${menu_list} '${item_num} xen_options'	'Xen options >>'	'Customize xen options: xen_hap:${xen_hap} xen_nestedhvm:${xen_nestedhvm}'"
	inc_menu_index item_num

	menu_list="${menu_list} '${item_num} exit_behavior'	'Exit behavior settings'	'Exit behavior settings: poweroff:${on_poweroff},reboot:${on_reboot},crash:${on_crash}'"
	inc_menu_index item_num

	if [ "${from_jail}" = "1" -a "${xen_profile}" != "FreeBSD-bsdinstall-jail" ]; then
		menu_list="${menu_list}	'-'				'JAIL SUB:'		'fromjail submenu'"
		[ -z "${swapsize}" ] && swapsize="4g"
		inc_menu_index item_let
		menu_list="${menu_list}	'${item_let} vm_guestfs'	'$(curval vm_guestfs)'	'Choose filesystem for boot image'"
		inc_menu_index item_let
		menu_list="${menu_list}	'${item_let} swapsize'		'$(curval swapsize)'	'Allocate and Configure for swap partition'"
		inc_menu_index item_let
		menu_list="${menu_list}	'${item_let} pkglist'		'$(curval pkgnum)'	'mark pkg for install from repo'"
		inc_menu_index item_let
		menu_list="${menu_list}	'${item_let} gw4'		'$(curval gw4)'		'Default router for xen or vimage'"
		inc_menu_index item_let
		menu_list="${menu_list}	'${item_let} ver'		'$(curval ver)'		'choose code base version'"
		inc_menu_index item_let
		menu_list="${menu_list}	'${item_let} applytpl'		'$(curval applytpl)'	'Apply cbsd templates'"
		inc_menu_index item_let
		menu_list="${menu_list}	'${item_let} floatresolv'	'$(curval floatresolv)'	'Auto correct for jail resolv.conf'"
		inc_menu_index item_let
		menu_list="${menu_list}	'${item_let} arch'		'$(curval arch)'	'target arch'"
		inc_menu_index item_num
		menu_list="${menu_list}	'${item_num} user_pw_root'	'Root Password'		'Change jail root password'"
		inc_menu_index item_num
		menu_list="${menu_list}	'${item_num} add_user'		'$(curval user_add)'	'Create additional account within VM'"
		inc_menu_index item_num
		menu_list="${menu_list}	'${item_num} services'		'Services >>'		'Toggle Startup Services'"
		inc_menu_index item_num
		menu_list="${menu_list}	'${item_num} pkglist'		'$(curval pkgnum)'	'mark pkg for install from repo'"
	fi

	menu_list="${menu_list}	'-'			'-'					'fromjail submenu'"
	inc_menu_index item_num
	menu_list="${menu_list}	'${item_num} GO'	'PROCEED!'				'PROCEED!'"

	if [ -n "${extra_default_item}" ]; then
		# scan for extra default item in menu list
		OIFS="${IFS}"
		IFS="'"
		for i in ${menu_list}; do
			IFS="${OIFS}"
			case "${i}" in
				[0-9]*${extra_default_item}|[aA-zZ]*${extra_default_item})
					defaultitem="${i}"
					break
					;;
			esac
		done
		IFS="${OIFS}"
	fi
	cbsd_menubox_with_help
	retval=$?

	f_dialog_data_sanitize menu_choice
	f_dialog_menutag_store "$menu_choice"
	f_dialog_default_store "$menu_choice"

	return $retval
}

#### [ MAIN AREA ] ####
[ ! -f ${localcbsdconf} ] && err 1 "${N1_COLOR}no such conf file${N0_COLOR}"
. ${localcbsdconf}
. ${inventory}

zero_profile="xen-default-default.conf"
default_profile="xen-default-default.conf"

#defaults
. ${subrdir}/build.subr

# read for skip_xen_init_warning
readconf ${default_profile}
init_xen
readconf vnc.conf
readconf spice.conf

# re-read profile for init global_profile_file variable
get_construct_profile ${default_profile}
[ -z "${profile}" -a -n "${jail_profile}" ] && profile="${jail_profile}"

[ -z "${xen_vnc_resolution}" ] && xen_vnc_resolution="${default_vnc_width}x${default_vnc_height}"
[ -z "${xen_vnc_tcp_bind}" ] && xen_vnc_tcp_bind="${default_vnc_tcp_bind}"
[ -z "${xen_vnc_vgaconf}" ] && xen_vnc_vgaconf="${default_vnc_vgaconf}"
[ -z "${vnc_password}" ] && vnc_password="${default_vnc_password}"
[ -z "${xen_spice_resolution}" ] && xen_spice_resolution="${default_spice_width}x${default_spice_height}"
[ -z "${xen_spice_tcp_bind}" ] && xen_spice_tcp_bind="${default_spice_tcp_bind}"

# IPv6 only host?
case "${node_ip6_active}" in
	1)
		if [ "${node_ip4_active}" = "0" ]; then
			default_spice_tcp_bind="[::1]"
		fi
		;;
esac

[ -z "${spice_password}" ] && spice_password="${default_spice_password}"
[ -z "${imgtype}" ] && imgtype="zvol"
[ -z "${uuid}" ] && uuid="0"

baserw=1
ip4_addr="DHCP"
jprofile="default"
cloud_init_options=

f_dialog_title "$msg_system_console_configuration"
f_dialog_backtitle "${ipgm:+bsdconfig }$pgm"
f_mustberoot_init

# init first bconstruct settings
if [ ! -r ${tmpdir}/xconstruct.conf ]; then
	${CAT_CMD} > ${tmpdir}/xconstruct.conf <<EOF
last_vm_os_type="freebsd"
last_vm_os_profile="FreeBSD-x64-13.0"
EOF
fi

if [ "${default_profile}" = "default" -a -r ${tmpdir}/xconstruct.conf ]; then
	[ -r ${tmpdir}/get_construct_vm_os_profile.menu ] && ${RM_CMD} -f ${tmpdir}/get_construct_vm_os_profile.menu
	. ${tmpdir}/xconstruct.conf
	if [ -n "${last_vm_os_type}" ]; then
		vm_os_type="${last_vm_os_type}"
		get_construct_vm_os_type ${vm_os_type}
	fi
	if [ -n "${last_vm_os_profile}" ]; then
		vm_os_profile="${last_vm_os_profile}"
		get_construct_vm_os_profile ${vm_os_profile}
	fi
else
	vm_iso_path="${register_iso_as}"
	apply_vm_package
fi

while [ 1 ]; do
	pkgnum=0
	[ -n "${pkglist}" -a "${pkglist}" != "NO" ] && pkgnum=$( ${WC_CMD} -w ${pkglist} | ${AWK_CMD} '{printf $1}' )

	dialog_menu_main
	retval=$?

	if [ $retval -eq $DIALOG_HELP ]; then
		get_help
		continue
	elif [ $retval -ne $DIALOG_OK ]; then
		f_die
	fi

	index=${mtag%% *}
	mychoice=${mtag##* }

	case "${mychoice}" in
		"EXIT")
			exit 0
			;;
		"GO")
			# store last choices
			${SYSRC_CMD} -qf ${tmpdir}/xconstruct.conf last_vm_os_type="${vm_os_type}" > /dev/null 2>&1
			${SYSRC_CMD} -qf ${tmpdir}/xconstruct.conf last_vm_os_profile="${vm_os_profile}" > /dev/null 2>&1
			gen_newjail_conf
			;;
		"-")
			continue
			;;
		interface)
			get_construct_interface -d 1 -s "tap vboxnet lo xnb wlan" -b 1 -v 1 -n 1
			;;
		astart)
			invert_checkbox ${mychoice}
			continue
			;;
		*)
			get_construct_${mychoice}
			;;
	esac
done

exit 0
