#!/usr/local/bin/cbsd
. ${subrdir}/nc.subr

############################################################ FUNCTIONS

# dialog_menu_main
#
# Display the dialog(1)-based application main menu.
#
dialog_menu_main()
{
	local _input _retval

	local btitle="$DIALOG_BACKTITLE"

	local title=" CPU topology list "
	hline=

	local prompt="${_desc}"
	local sqldelimer=" "

	local mark
	local menu_list=$( cbsdsqlro local "SELECT name,sockets,cores,threads FROM vm_cpu_topology" | while read name sockets cores threads; do
		eval mark=\$topology_selected_${name}
		if [ "${mark}" = "1" ]; then
			mark="X"
		else
			mark=" "
		fi
		echo "'${name}'	'[${mark}] Sockets=${sockets},Cores=${cores},Threads=${threads}'	'description'"
	done ) || err 1 "${N1_COLOR}Error while create topology map${N0_COLOR}"


	[ -z "${menu_list}" ] && menu_list="''	'no data'	''"

	local height width rows
	eval f_dialog_menu_with_help_size height width rows \
		\"\$title\"  \
		\"\$btitle\" \
		\"\$prompt\" \
		\"\$hline\"  \
		$menu_list

	height=$(( height + 1 ))

	# when empty form
	[ $width -lt 42 ] && width=42

	# Obtain default-item from previously stored selection
	f_dialog_default_fetch defaultitem

	local menu_choice
	menu_choice=$( eval $DIALOG \
		--clear                                 \
		--title \"\$title\"                     \
		--backtitle \"\$btitle\"                \
		--hline \"\$hline\"                     \
		--item-help                             \
		--ok-label \"\$msg_ok\"                 \
		--cancel-label \"Remove\"               \
		--extra-button                          \
		--extra-label \"Add\"                   \
		--help-button				\
		--help-label \"Exit\"			\
		${USE_XDIALOG:+--help \"\"}             \
		--default-item \"\$defaultitem\"        \
		--menu \" \$prompt \"                   \
		$height $width $rows                    \
		$menu_list                              \
		2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
	)

	local retval=$?
	f_dialog_data_sanitize menu_choice
	f_dialog_menutag_store "$menu_choice"

	# Only update default-item on success
	[ $retval -eq $DIALOG_OK ] && f_dialog_default_store "$menu_choice"
	return $retval
}


item_add()
{
	local _par VAL
	local btitle="$DIALOG_BACKTITLE"
	local prompt="Use menu for select and edit limit"
	local hline=

	local title=" Add new cpu topology "
	local _mydesc

	local name sockets cores threads description

	while [ 1 ]; do

		# default
		[ -z "${name}" ] && name="newtopology"
		[ -z "${sockets}" ] && sockets="1"
		[ -z "${cores}" ] && cores="1"
		[ -z "${threads}" ] && threads="1"

		local menu_list=

		menu_list="
			'name'		'${name}'	'name of the topology, one-word, e.g: dualsockets'
			'sockets'	'${sockets}'	'Number of sockets, e.g: 2'
			'cores'		'${cores}'	'Number of cores, e.g: 2'
			'threads'	'${threads}'	'Number of threads, e.g: 1'
		"

		menu_list="${menu_list} 'COMMIT'	'Save changes and quit'	'Save!'"

		local height width rows
		eval f_dialog_menu_with_help_size height width rows \
			\"\$title\"  \
			\"\$btitle\" \
			\"\$prompt\" \
			\"\$hline\"  \
			$menu_list

		height=$(( height + 1 ))

		# Obtain default-item from previously stored selection
		f_dialog_default_fetch defaultitem

		mtag=$( eval $DIALOG \
			--clear                                 \
			--title \"\$title\"                     \
			--backtitle \"\$btitle\"                \
			--hline \"\$hline\"                     \
			--item-help                             \
			--ok-label \"\$msg_ok\"                 \
			--cancel-label \"Exit\"                 \
			${USE_XDIALOG:+--help \"\"}             \
			--default-item \"\$defaultitem\"        \
			--menu \" \$prompt \"                   \
			$height $width $rows                    \
			$menu_list                              \
			2>&1 >&$DIALOG_TERMINAL_PASSTHRU_FD
		)

		local retval=$?
		f_dialog_data_sanitize mtag
		f_dialog_menutag_store "$mtag"

		# Only update default-item on success
		[ $retval -eq $DIALOG_OK ] && f_dialog_default_store "$mtag"

		case ${retval} in
			${DIALOG_OK})
				if [ "${mtag}" = "COMMIT" ]; then
					[ -z "${name}" ] && f_dialog_msgbox "name must be filled" && continue
					[ -z "${sockets}" ] && f_dialog_msgbox "sockets must be filled" && continue
					[ -z "${cores}" ] && f_dialog_msgbox "cores must be filled" && continue
					[ -z "${threads}" ] && f_dialog_msgbox "threads must be filled" && continue
					cbsdsqlrw local "INSERT INTO vm_cpu_topology ( name,description,sockets,cores,threads ) VALUES ( '${name}','${name}','${sockets}','${cores}','${threads}' )"
					return ${retval}
				else
					get_construct_vm_cpu_topology_${mtag}
					continue
				fi
				;;
			${DIALOG_CANCEL})
				return $retval
				;;
			*)
				return ${retval}
				;;
		esac
	done

}

get_construct_vm_cpu_topology_name()
{
	title=" name "
	local name_msg="topology name, one word. must begin with a letter / a-z / and\nnot have any special symbols: -,.=%"
	defaultitem="${name}"
	local _ok=0 _message _input _retval _ret

	while [ ${_ok} -ne 1 ]; do
		f_dialog_input _input "${name_msg}" "${name}" \
			"${_message}" || return $?

		validate_jname "${_input}"
		case $? in
			0)
				_res=$( cbsdsqlro local "SELECT id FROM vm_cpu_topology WHERE name='${_input}' LIMIT 1" )
				if [ -n "${_res}" ]; then
					_message="ERROR: topology ${_input} already exist"
				else
					_ok=1
				fi
				;;
			*)
				_message="ERROR: bad name. choose other one"
				;;
		esac
	done

	[ -n "${_input}" ] && name="${_input}"
}

get_construct_vm_cpu_topology_sockets()
{
	title=" Sockets "
	prompt=" Enter sockets, e.g: 2 "
	defaultitem="${sockets}"
	cbsd_inputbox_simple && sockets="${mtag}"
}

get_construct_vm_cpu_topology_cores()
{
	title=" Cores "
	prompt=" Enter Cores, e.g: 2 "
	defaultitem="${cores}"
	cbsd_inputbox_simple && cores="${mtag}"
}

get_construct_vm_cpu_topology_threads()
{
	title=" Threads "
	prompt=" Enter Threads, e.g: 1 "
	defaultitem="${threads}"
	cbsd_inputbox_simple && threads="${mtag}"
}


item_remove()
{
	[ -z "${mark_list}" ] && return 0

	local _i

	for _i in ${mark_list}; do
		cbsdsqlrw local "DELETE FROM vm_cpu_topology WHERE name='${_i}'"
	done

	unset mark_list
	return 0
}


############################################################ MAIN
export NOCOLOR=1

MYARG=""
MYOPTARG=""
MYDESC="Edit CPU topology"
CBSDMODULE="bhyve"

. ${cbsdinit}

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

#
# Process command-line arguments
#
while getopts h$GETOPTS_STDARGS flag; do
	case "$flag" in
	h|\?) f_usage $BSDCFG_LIBE/$APP_DIR/USAGE "PROGRAM_NAME" "$pgm" ;;
	esac
done
shift $(( $OPTIND - 1 ))

#
# Initialize
#
f_dialog_title " cpu-topology "
f_dialog_backtitle "${ipgm:+bsdconfig }$pgm"
f_mustberoot_init


mark_list=

#
# Loop over the main menu until we've accomplished what we came here to do
#
while :; do
	dialog_menu_main
	ret=$?

	case $ret in
		${DIALOG_OK})
			f_dialog_menutag_fetch mtag
			case "${mtag}" in
				?" ${msg_exit}")
					break
					;;
				"-")
					continue
					;;
				*)
					vhid=${mtag%% *}
					# val=${mtag##* }
					eval mark=\$topology_selected_${vhid}
					if [ "${mark}" = "1" ];then
						eval "topology_selected_${vhid}=\"0\""
						old_mark_list="${mark_list}"
						mark_list=
						for i in ${old_mark_list}; do
							[ "${i}" != "${vhid}" ] && mark_list="${mark_list} ${i}"
						done
					else
						eval "topology_selected_${vhid}=\"1\""
						mark_list="${mark_list} ${vhid}"
					fi
					;;
			esac
			;;
		${DIALOG_CANCEL})
			item_remove
			continue
			;;
		${DIALOG_EXTRA})
			item_add
			continue
			;;
		*)
			f_die
			;;
	esac
done

return $SUCCESS

################################################################################
# END
################################################################################
