#!/bin/bash -login

# Copyright (C) 2010-2024 Pädagogisches Landesinstitut Rheinland-Pfalz
# Copyright (C) 2022-2023 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
# Copyright (C) 2022-2024 Daniel Teichmann <daniel.teichmann@das-netzwerkteam.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

export PATH="/bin:/sbin:/usr/bin:/usr/sbin"

export TEXTDOMAIN="debian-edu-router-config"

# source gettext tools
. gettext.sh

if [ -e /etc/debian-edu/router.conf ]; then
	source /etc/debian-edu/router.conf
fi
PRODUCTNAME="${PRODUCTNAME:-$(eval_gettext "Debian Edu Router")}"
PRODUCTNAME_PLUGIN_SUFFIX="${PRODUCTNAME_PLUGIN_SUFFIX:-$(eval_gettext "Plugin")}"

# Declare a bunch of associative arrays to store plugin data.
declare -a plugins_name
# The key of below arrays is always a plugin_name
declare -A plugins_description
declare -A plugins_is_enabled_file
declare -A plugins_package_name
declare -A plugins_package_version
declare -A plugins_conf_submenu_enabled

declare -A plugins_conf_submenu_items
declare -A plugins_conf_submenu_item_command
declare -A plugins_conf_submenu_item_text
declare -A plugins_conf_submenu_item_key

declare -A plugins_menu_key
# Available keys for plugins (This would limit us to a max of 10 plugins (for now)!)
# TODO: Implement this differently somehow.
AVAILABLE_PLUGIN_ITEM_KEY=(1 2 3 4 5 6 7 8 9 0)
plugin_item_key_indexer=0

# (Mandatory) $PLUGIN_NAME
# (Mandatory) $PLUGIN_DESCRIPTION
# (Mandatory) $PLUGIN_IS_ENABLED_FILE
# (Mandatory) $PLUGIN_PACKAGE_NAME
# (Mandatory) $PLUGIN_PACKAGE_VERSION
# (Mandatory) $PLUGIN_CONF_SUBMENU_ITEMS
function register_plugin() {
	#echo "» Registering plugin: '$PLUGIN_NAME'..."
	#echo "» $PLUGIN_DESCRIPTION"
	#echo "» PLUGIN_PACKAGE_NAME:         $PLUGIN_PACKAGE_NAME"
	#echo "» PLUGIN_PACKAGE_VERSION:      $PLUGIN_PACKAGE_VERSION"
	#echo "» PLUGIN_CONF_SUBMENU_ITEMS:   $PLUGIN_CONF_SUBMENU_ITEMS"
	#echo; echo

	plugins_name+=("$PLUGIN_NAME")
	plugins_description[$PLUGIN_NAME]="$PLUGIN_DESCRIPTION"
	plugins_is_enabled_file[$PLUGIN_NAME]="$PLUGIN_IS_ENABLED_FILE"
	plugins_package_name[$PLUGIN_NAME]="$PLUGIN_PACKAGE_NAME"
	plugins_package_version[$PLUGIN_NAME]="$PLUGIN_PACKAGE_VERSION"
	plugins_conf_submenu_items[$PLUGIN_NAME]="${PLUGIN_CONF_SUBMENU_ITEMS[@]}"

	# Assign this new plugin a key which the user has to press in order to
	# configure it.
	plugins_menu_key[$PLUGIN_NAME]="${AVAILABLE_PLUGIN_ITEM_KEY[$plugin_item_key_indexer]}"

	# Check if submenu items are specified and load them.
	if [[ "${#PLUGIN_CONF_SUBMENU_ITEMS[@]}" -gt 0 ]]; then
		plugins_conf_submenu_enabled[$PLUGIN_NAME]=true

		for item in ${plugins_conf_submenu_items["$PLUGIN_NAME"]}; do
			# now load submenu items
			var_name_item_command="PLUGIN_CONF_SUBMENU_ITEM_COMMAND_$item"
			var_name_item_text="PLUGIN_CONF_SUBMENU_ITEM_TEXT_$item"
			var_name_item_key="PLUGIN_CONF_SUBMENU_ITEM_KEY_$item"

			item_command="${!var_name_item_command}"
			item_text="${!var_name_item_text}"
			item_key="${!var_name_item_key}"

			plugins_conf_submenu_item_command[$PLUGIN_NAME,$item]="$item_command"
			plugins_conf_submenu_item_text[$PLUGIN_NAME,$item]="$item_text"
			plugins_conf_submenu_item_key[$PLUGIN_NAME,$item]="$item_key"
		done
	fi

	plugin_item_key_indexer=$((plugin_item_key_indexer+1))
}

function reload_plugins() {
	# Reset registered plugins.
	unset plugins_name;                      declare -g -a plugins_name
	unset plugins_menu_key;                  declare -g -A plugins_menu_key
	unset plugins_description;               declare -g -A plugins_description
	unset plugins_is_enabled_file;           declare -g -A plugins_is_enabled_file
	unset plugins_package_name;              declare -g -A plugins_package_name
	unset plugins_package_version;           declare -g -A plugins_package_version
	unset plugins_conf_submenu_enabled;      declare -g -A plugins_conf_submenu_enabled
	unset plugins_conf_submenu_items;        declare -g -A plugins_conf_submenu_items
	unset plugins_conf_submenu_item_command; declare -g -A plugins_conf_submenu_item_command
	unset plugins_conf_submenu_item_text;    declare -g -A plugins_conf_submenu_item_text
	unset plugins_conf_submenu_item_key;     declare -g -A plugins_conf_submenu_item_key
	plugin_item_key_indexer=0

	PLUGINS_PATH="/usr/share/debian-edu-router-plugins"
	if [[ -e "$PLUGINS_PATH" && -d "$PLUGINS_PATH" ]]; then
		shopt -s nullglob # Prevent taking '$PLUGINS_PATH/d-e-r-p.*.sh' literally.
		for plugin_conf_file_path in $PLUGINS_PATH/d-e-r-p.*.sh; do
			source "$plugin_conf_file_path"

			# TODO: Check if package is actually installed
			# (with $PLUGIN_PACKAGE_NAME) if not: Then skip registering this plugin.

			register_plugin
		done
		# unset it now
		shopt -u nullglob

		# Reset TEXTDOMAIN again.
		export TEXTDOMAIN="debian-edu-router-config"

	#else
		#echo `printf "$(eval_gettext "Plugin config file path '%s' could not be found!")" "$PLUGINS_PATH"`
		#echo "$(eval_gettext "This probably means that there are no plugins installed.")"
	fi
}

# for system info
. /etc/os-release

WELCOME_HEADER=`printf "$(eval_gettext "Welcome to %s %s (%s) on %s")" "${NAME}" "${VERSION}" "$(uname -m)" "${HOSTNAME}"`
NETWORK_DOWN="$(eval_gettext "WARNING: All networks are currently down. Check your configuration.")"
LDAP_DOWN="$(eval_gettext "WARNING: LDAP connection is currently down.
Please check if SSL certificates are needed (they can be installed in the plugin menu) and
check your configuration. Use debian-edu-router_ldapsearch as a test command.")"
MACHINE_ID=$(eval_gettext "machine ID")

MENU_HEADER=`printf "$(eval_gettext "%s Menu")" "${PRODUCTNAME}"`
SELECT_MSG=$(eval_gettext "Please select: ")
HIT_ENTER_TO_CONTINUE=$(eval_gettext "Hit <ENTER> to continue...")

# Open Shell
ITEM_SHELL=$(eval_gettext "Launch a shell session")
CMD_CHOSEN_SHELL=`printf "$(eval_gettext "Starting shell '%s'...")" "${SHELL}"`

# Base Configuration
ITEM_SETUP_BASE=`printf "$(eval_gettext "%s Base Configuration")" "${PRODUCTNAME}"`
CMD_CHOSEN_SETUP_BASE=`printf "$(eval_gettext "Entering %s base configuration submenu...")" "${PRODUCTNAME}"`

# Tools Submenu
SUBMENU_TOOLSMENU_HEADER=`printf "$(eval_gettext "%s Handy tools and tricks")" "${PRODUCTNAME}"`
ITEM_TOOLSMENU="Handy tools and tricks"
CMD_CHOSEN_TOOLSMENU=$(eval_gettext "Opening tools menu...")
# IP statistics
ITEM_IPTRAF=$(eval_gettext "Run IP traffic statistics utility")
CMD_CHOSEN_IPTRAF=$(eval_gettext "Starting IPTRAF traffic monitor...")
# HTOP
ITEM_HTOP="$(eval_gettext "Run htop utility")"
CMD_CHOSEN_HTOP="$(eval_gettext "Starting htop utility...")"
# D-E-R Logview (mcview)
ITEM_LOGVIEW="$(eval_gettext "Show log files")"
CMD_CHOSEN_LOGVIEW="$(eval_gettext "Starting logview utility...")"
# DNSMASQ DHCP leases
ITEM_DHCP_LEASES="$(eval_gettext "Show DHCP leases (%s)")"
CMD_CHOSEN_DHCP_LEASES="$(eval_gettext "Showing DHCP leases of dnsmasq services...")"

# Base Configuration Submenu
SUBMENU_SETUP_BASE_HEADER=`printf "$(eval_gettext "%s Base Configuration")" "${PRODUCTNAME}"`
ITEM_DER_ALL_SETUP=`printf "$(eval_gettext "Configure %s base system entirely")" "${PRODUCTNAME}"`
ITEM_DER_NETWORK_SETUP=`printf "$(eval_gettext "Configure %s network settings")" "${PRODUCTNAME}"`
ITEM_DER_FIREWALL_SETUP=`printf "$(eval_gettext "Configure %s firewall settings")" "${PRODUCTNAME}"`
ITEM_DER_SERVICES_SETUP=`printf "$(eval_gettext "Configure %s services")" "${PRODUCTNAME}"`
CMD_CHOSEN_ALL=$(eval_gettext "Configure everything...")
CMD_CHOSEN_NETWORKSETUP=$(eval_gettext "Configure networking...")
CMD_CHOSEN_FIREWALLSETUP=$(eval_gettext "Configure firewall settings...")
CMD_CHOSEN_SERVICESSETUP=$(eval_gettext "Configure services...")
CMD_CHOSEN_BACK_PLUGINMENU=$(eval_gettext "Back to plugin menu")
CMD_CHOSEN_BACK=$(eval_gettext "Back to main menu")

# Plugin Configuration
ITEM_SETUP_PLUGINS=`printf "$(eval_gettext "%s Plugin Configuration")" "${PRODUCTNAME}"`
CMD_CHOSEN_SETUP_PLUGINS=`printf "$(eval_gettext "Entering %s plugin configuration submenu...")" "${PRODUCTNAME}"`

# Plugins Configuration Submenu
SUBMENU_SETUP_PLUGINS_HEADER=`printf "$(eval_gettext "%s Plugin Configuration")" "${PRODUCTNAME}"`
SUBMENU_SETUP_PLUGINS_HELPTEXT_CHECKMARK="$(eval_gettext "Plugins marked with '[X]' are enabled, '[ ]' means they are disabled.")"

# Reboot stuff
ITEM_REBOOT="$(eval_gettext "Reboot system")"
ITEM_REBOOT_SELECT_MSG=$(eval_gettext "Are you sure you want to reboot the system? Type in 'imsure':")
ITEM_REBOOT_DISCLAIMER=$(eval_gettext "WARNING!
Make sure you still have (physical) access to the machine in case the boot
process fails. If this is a VM Guest, make sure you have access to the
VM Host. An internet downage can easily ruin your day!
You have been warned.")
ITEM_REBOOT_VALID_INPUT=$(eval_gettext "imsure")
ITEM_REBOOT_SLEEP_TIME="5"
ITEM_REBOOT_REBOOTING_NOW=`printf "$(eval_gettext "OK. Rebooting %s in %s seconds!")" "${PRODUCTNAME}" "${ITEM_REBOOT_SLEEP_TIME}"`

# Shutdown stuff
ITEM_SHUTDOWN="$(eval_gettext "Shut down system")"
ITEM_SHUTDOWN_SELECT_MSG=$(eval_gettext "Are you sure you want to shut down the system? Type in 'imsure':")
ITEM_SHUTDOWN_DISCLAIMER=$(eval_gettext "WARNING!
Make sure you still have (physical) access to the machine!
If this is a VM Guest, make sure you have access to the
VM Host. An internet outage can easily ruin your day!
You have been warned.")
ITEM_SHUTDOWN_VALID_INPUT=$(eval_gettext "imsure")
ITEM_SHUTDOWN_SLEEP_TIME="5"
ITEM_SHUTDOWN_SHUTTING_DOWN_NOW=`printf "$(eval_gettext "OK. Shutting down %s in %s seconds!")" "${PRODUCTNAME}" "${ITEM_SHUTDOWN_SLEEP_TIME}"`

# Debug Mode
ITEM_DEBUG_TURN_ON="$(eval_gettext "Toggle debug messages on")"
ITEM_DEBUG_TURN_OFF="$(eval_gettext "Toggle debug messages off")"
if [[ -e "/etc/debian-edu-router/debug" ]]; then
	ITEM_DEBUG="${ITEM_DEBUG_TURN_OFF}"
else
	ITEM_DEBUG="${ITEM_DEBUG_TURN_ON}"
fi
ITEM_DEBUG_ON="$(eval_gettext "Enabling debug messages...")"
ITEM_DEBUG_RECONFIGURING_PACKAGES=`printf "$(eval_gettext "Reconfiguring %s + Plugins...")" "${PRODUCTNAME}"`
ITEM_DEBUG_OFF="$(eval_gettext "Disabling debug messages...")"
CMD_CHOSEN_DEBUG="$(eval_gettext "Toggling...")"

# Quit
ITEM_QUIT=`printf "$(eval_gettext "Quit menu and log out as user '%s'")" "${USER}"`
ITEM_QUIT_PLUGIN_SUBMENU=$(eval_gettext "Return back to plugin menu")
ITEM_QUIT_SUBMENU=$(eval_gettext "Return back to main menu")
CMD_CHOSEN_QUIT=$(eval_gettext "Quit")

ETCKEEPER_PRE_TEXT="$(eval_gettext "Saving changes to /etc via 'etckeeper'...")"
ETCKEEPER_COMMIT_TEXT="$(eval_gettext "Loginmenu was used to configure '%s'.")"

underline() { echo $1; echo "${1//?/${2:-=}}";}

fill_with_trailing_blanks() {
	length=$1
	string=$2
	printf "%-${length}s" "${string}"
}

header() {
	echo -e "\033[1m*** ${WELCOME_HEADER} ***\033[0m"
	echo

	echo -n "${PRODUCTNAME} ($(dpkg-query -f='${Version}\n' -W debian-edu-router-config))"
	if [ -e /etc/machine-id ]; then
		echo ", ${MACHINE_ID}: $(cat /etc/machine-id)"
	else
		echo
	fi
	echo

	ip_addresses_shown=false

	cd /etc/network/interfaces.d/
	configs="$(find . -name '*d-e-r*' | sort | grep -v VLAN)"
	if [ -n "${configs}" ]; then
		for ifaceconf in ${configs}; do
			if [ -e "${ifaceconf}" ]; then
				iface=`cat "${ifaceconf}" | grep -E "^iface .*" | cut -d " " -f2`
				if [ -n "$iface" ]; then
					network=`echo "${ifaceconf}" | cut -d"_" -f3`
					addr_v4=`ip a show ${iface} 2>/dev/null | grep "inet " | awk '{print $2}' | head -n1`
					macaddress=`ip addr show ${iface} | grep "link/ether" | grep -o -E ..:..:..:..:..:.. | head -1`
					if [ -n "${addr_v4}" ]; then
						echo "`fill_with_trailing_blanks 24 ${network}`-> `fill_with_trailing_blanks 10 $iface` -> v4: `fill_with_trailing_blanks 18 ${addr_v4}` [${macaddress}]"
						ip_addresses_shown=true
					fi
				fi
			fi
		done
		if [ ${ip_addresses_shown} = false ]; then
			echo -e "\033[1m${NETWORK_DOWN}\033[0m"
		fi
		echo
	fi

	check_ldap_connection

	echo
	cd - 1>/dev/null
}

check_ldap_connection() {
	if ! [[ -e "/var/lib/debian-edu-router/d-e-r-p.l-c/enabled" ]]; then
		return
	fi

	if ! /usr/sbin/debian-edu-router_ldapsearch >/dev/null 2>&1; then
		echo -e "\033[1m${LDAP_DOWN}\033[0m"
	fi
}

submenu_tools() {
	local iptraf_enabled=""
	if command -v iptraf >/dev/null 2>&1; then
		iptraf_enabled="\t i - ${ITEM_IPTRAF}\n"
	fi

	local htop_enabled=""
	if command -v htop >/dev/null 2>&1; then
		htop_enabled="\t h - ${ITEM_HTOP}\n"
	fi

	local logview_enabled=""
	if command -v debian-edu-router_logview >/dev/null 2>&1; then
		logview_enabled="\t v - ${ITEM_LOGVIEW}\n"
	fi

	local DHCP_LEASES_FILE="/var/lib/misc/dnsmasq.leases"
	local dhcp_leases_enabled=""
	local dhcp_leases_count=
	if [[ -e "${DHCP_LEASES_FILE}" ]]; then
		dhcp_leases_count="$(cat ${DHCP_LEASES_FILE} | wc -l)"
		dhcp_leases_enabled="\t l - $(printf "${ITEM_DHCP_LEASES}" "${dhcp_leases_count}")\n"
	fi

	local t
	local command_executed=""
	while true; do
		echo -e "\033[1m$(underline "${SUBMENU_TOOLSMENU_HEADER}" "-")\n\n"       \
				"${iptraf_enabled}"                                               \
				"${htop_enabled}"                                                 \
				"${logview_enabled}"                                              \
				"${dhcp_leases_enabled}"                                          \
				"\t m - ${ITEM_QUIT_SUBMENU}\n"                                   \
				"\033[0m"
		read -p "
[1m${SELECT_MSG}[0m" -s -n 1 t
		case "$t" in
			[iI]) [[ -n "${iptraf_enabled}" ]]      && echo -e "\033[1m${CMD_CHOSEN_IPTRAF}\033[0m"      && iptraf                     && command_executed="true";;
			[hH]) [[ -n "${htop_enabled}" ]]        && echo -e "\033[1m${CMD_CHOSEN_HTOP}\033[0m"        && htop                       && command_executed="true";;
			[vV]) [[ -n "${logview_enabled}" ]]     && echo -e "\033[1m${CMD_CHOSEN_LOGVIEW}\033[0m"     && debian-edu-router_logview  && command_executed="true";;
			[lL]) [[ -n "${dhcp_leases_enabled}" ]] && echo -e "\033[1m${CMD_CHOSEN_DHCP_LEASES}\033[0m" && less "${DHCP_LEASES_FILE}" && command_executed="true";;
			[mM]) echo -e "\033[1m${CMD_CHOSEN_BACK}\033[0m"; break;;
		esac

		if [[ -n "${command_executed}" ]]; then
			command_executed=""
			echo
			read -p "[1m${HIT_ENTER_TO_CONTINUE}[0m" -s -n 1 treset;
			reset
			echo
			header
		fi
	done
	sleep 1
}

submenu_reboot() {
	local t

	echo -e "${ITEM_REBOOT_DISCLAIMER}"
	read -p "
[1m${ITEM_REBOOT_SELECT_MSG}[0m " t
	case "$t" in
		${ITEM_REBOOT_VALID_INPUT}) echo -e "\033[1m${ITEM_REBOOT_REBOOTING_NOW}\033[0m"; sleep "$ITEM_REBOOT_SLEEP_TIME"; reboot now;;
		*) echo -e "\033[1m${CMD_CHOSEN_BACK}\033[0m"; echo;;
	esac
	echo

	sleep 1
}

submenu_shutdown() {
	local t

	echo -e "${ITEM_SHUTDOWN_DISCLAIMER}"
	read -p "
[1m${ITEM_SHUTDOWN_SELECT_MSG}[0m " t
	case "$t" in
		${ITEM_SHUTDOWN_VALID_INPUT}) echo -e "\033[1m${ITEM_SHUTDOWN_SHUTTING_DOWN_NOW}\033[0m"; sleep "$ITEM_SHUTDOWN_SLEEP_TIME"; shutdown now;;
		*) echo -e "\033[1m${CMD_CHOSEN_BACK}\033[0m"; echo;;
	esac
	echo

	sleep 1
}

submenu_debug() {
	local t

	if [ -e "/etc/debian-edu-router/debug" ]; then
		echo "${ITEM_DEBUG_OFF}"
		rm -f /etc/debian-edu-router/debug
	else
		echo "${ITEM_DEBUG_ON}"
		touch /etc/debian-edu-router/debug
	fi

	echo "${ITEM_DEBUG_RECONFIGURING_PACKAGES}"
	dpkg-trigger --no-await debian-edu-router-reconfigured
	SKIP_DEBCONF_QUESTIONS_CONFIG=1 dpkg-reconfigure debian-edu-router-config || true
	SKIP_DEBCONF_QUESTIONS_CONFIG=1 dpkg --configure -a                       || true

	if [[ -e "/etc/debian-edu-router/debug" ]]; then
		ITEM_DEBUG="${ITEM_DEBUG_TURN_OFF}"
	else
		ITEM_DEBUG="${ITEM_DEBUG_TURN_ON}"
	fi

	sleep 1
	echo
	read -p "[1m${HIT_ENTER_TO_CONTINUE}[0m" -s -n 1 t
}

function etckeeper_saves_changes() {
	local plugin_name="$1"

	if command -v etckeeper >/dev/null 2>&1; then
		echo "${ETCKEEPER_PRE_TEXT}"

		if [[ -n "${plugin_name}" ]]; then
			etckeeper commit "$(printf "${ETCKEEPER_COMMIT_TEXT}" "${plugin_name}")"
		else
			etckeeper commit "$(printf "${ETCKEEPER_COMMIT_TEXT}" "${PRODUCTNAME}")"
		fi
	fi
}

submenu_setup_base() {
	local t
	while true; do
		echo -e "\033[1m$(underline "${SUBMENU_SETUP_BASE_HEADER}" "-")\n\n" \
				"\t a - ${ITEM_DER_ALL_SETUP}\n"                        \
				"\t n - ${ITEM_DER_NETWORK_SETUP}\n"                    \
				"\t f - ${ITEM_DER_FIREWALL_SETUP}\n"                   \
				"\t s - ${ITEM_DER_SERVICES_SETUP}\n"                   \
				"\t m - ${ITEM_QUIT_SUBMENU}\n"                         \
				"\033[0m"
		read -p "
[1m${SELECT_MSG}[0m" -s -n 1 t
		case "$t" in
			[aA]) echo -e "\033[1m${CMD_CHOSEN_ALL}\033[0m";           CONFIGURE_ONLY=""             dpkg-reconfigure debian-edu-router-config; echo; etckeeper_saves_changes;;
			[nN]) echo -e "\033[1m${CMD_CHOSEN_NETWORKSETUP}\033[0m";  CONFIGURE_ONLY="NETWORK_ALL"  dpkg-reconfigure debian-edu-router-config; echo; etckeeper_saves_changes;;
			[fF]) echo -e "\033[1m${CMD_CHOSEN_FIREWALLSETUP}\033[0m"; CONFIGURE_ONLY="FIREWALL_ALL" dpkg-reconfigure debian-edu-router-config; echo; etckeeper_saves_changes;;
			[sS]) echo -e "\033[1m${CMD_CHOSEN_SERVICESSETUP}\033[0m"; CONFIGURE_ONLY="SERVICES_ALL" dpkg-reconfigure debian-edu-router-config; echo; etckeeper_saves_changes;;
			[mM]) echo -e "\033[1m${CMD_CHOSEN_BACK}\033[0m"; echo; break;;
		esac
		echo
	done
	sleep 1
}

submenu_setup_plugins() {
	reload_plugins

	echo -e "\033[1m$(underline "${SUBMENU_SETUP_PLUGINS_HEADER}" "-")\n" \
			"\033[0m"
	# List plugins
	for plugin_name in "${plugins_name[@]}"; do
		# Get assigned key which shall be pressed by user to configure the plugin
		item_key="${plugins_menu_key[$plugin_name]}"

		# TODO: Group plugins by submenu enabled for a nicer visual appereance
		# TODO: Group plugins alphabetically

		# Either say 'Open configuration menu' or 'Configure entirely'
		if [[ ${plugins_conf_submenu_enabled["$plugin_name"]} == true ]]; then
			PLUGIN_MENU_TEXT=`printf "$(eval_gettext "%s » Open configuration menu")" "$plugin_name"`
		else
			PLUGIN_MENU_TEXT=`printf "$(eval_gettext "%s » Configure entirely")" "$plugin_name"`
		fi

		if [[ -s "${plugins_is_enabled_file[$plugin_name]}" ]]; then
			PLUGIN_MENU_TEXT="[X] ${PLUGIN_MENU_TEXT}"
		else
			PLUGIN_MENU_TEXT="[ ] ${PLUGIN_MENU_TEXT}"
		fi

		echo -e "\033[1m\t $item_key - $PLUGIN_MENU_TEXT"
	done

	echo -e "\t m - ${ITEM_QUIT_SUBMENU}\n"
	echo -e "\t ${SUBMENU_SETUP_PLUGINS_HELPTEXT_CHECKMARK}\n"

	while true; do
		read -p "
[1m${SELECT_MSG}[0m" -s -n 1 t

		case "$t" in
			[mM]) echo -e "\033[1m${CMD_CHOSEN_BACK}\033[0m"; echo; return 0;;
		esac

		# handle plugins
		found=false
		for plugin_name in "${plugins_name[@]}"; do
			# Get assigned key which shall be pressed by user to configure the plugin
			item_key="${plugins_menu_key["$plugin_name"]}"

			if [[ "$item_key" == "$t" ]]; then
				if [[ ${plugins_conf_submenu_enabled["$plugin_name"]} == true ]]; then
					submenu_plugin "$plugin_name"
					submenu_setup_plugins # Recursively open plugin setup menu.
					return 0
				else
					_text_configuring_now=`printf "$(eval_gettext "Configuring %s now...")" "${plugin_name}"`
					echo -e "\033[1m$_text_configuring_now\033[0m";
					sleep 1
					echo
					CONFIGURE_ONLY="" dpkg-reconfigure "${plugins_package_name["$plugin_name"]}"
					echo
					read -p "[1m${HIT_ENTER_TO_CONTINUE}[0m" -s -n 1 t
				fi
				found=true
				return 0
			fi
		done
	done
}

# $1 plugin which the submenu should be opened for
submenu_plugin() {
	local t
	plugin_name="$1"

	while true; do
		echo -e "\033[1m$(underline "`printf "$(eval_gettext "Configuration of the %s")" "${plugin_name}"`" "-")\n\n"

		for item in ${plugins_conf_submenu_items[$plugin_name]}; do
			text="${plugins_conf_submenu_item_text[$plugin_name,$item]}"
			key="${plugins_conf_submenu_item_key[$plugin_name,$item]}"

			echo -e "\t ${key} - ${text}"
		done
		echo -e "\t m - ${ITEM_QUIT_PLUGIN_SUBMENU}\033[0m\n"

		read -p "
[1m${SELECT_MSG}[0m" -s -n 1 t

		local command_executed=""
		for item in ${plugins_conf_submenu_items[$plugin_name]}; do
			command="${plugins_conf_submenu_item_command[$plugin_name,$item]}"
			key="${plugins_conf_submenu_item_key[$plugin_name,$item]}"

			if [[ "$t" == "m" || "$t" == "M" ]]; then
				echo -e "\033[1m${CMD_CHOSEN_BACK_PLUGINMENU}\033[0m"; return
			fi

			# If user pressed right key, execute command
			if [[ "$t" == "$key" ]]; then
				echo; echo
				_text_configuring_now=`printf "$(eval_gettext "Configuring %s now...")" "${plugin_name}"`
				echo -e "\033[1m$_text_configuring_now\033[0m";
				sleep 1s

				# Tell following command that is was called via loginmenu.
				export D_E_R_LOGINMENU="true"
				eval "${command}"

				command_executed="true"
				echo
				break
			fi
		done

		if [[ -n "${command_executed}" ]]; then
			etckeeper_saves_changes "${plugin_name}"

			echo
			reload_plugins # reload, because tasks for example could change ITEM_TEXT, which should be taken account of.
			read -p "[1m${HIT_ENTER_TO_CONTINUE}[0m" -s -n 1 t
			echo
			reset
			echo
			header
		fi

		echo
	done
}

menu(){
	local t

	echo -e "\033[1m$(underline "${MENU_HEADER}")\n\n" \
	        "\t t - ${ITEM_TOOLSMENU}\n"               \
	        "\t s - ${ITEM_SHELL}\n"                   \
	        "\t c - ${ITEM_SETUP_BASE}\n"              \
	        "\t p - ${ITEM_SETUP_PLUGINS}\n"           \
	        "\t r - ${ITEM_REBOOT}\n"                  \
	        "\t x - ${ITEM_SHUTDOWN}\n"                \
	        "\t d - ${ITEM_DEBUG}\n"                   \
	        "\t q - ${ITEM_QUIT}\n"                    \
	        "\033[0m"

	while true; do
		read -p "
[1m${SELECT_MSG}[0m" -s -n 1 t
		case "$t" in
			[tT]) echo -e "\033[1m${CMD_CHOSEN_TOOLSMENU}\033[0m";     echo; submenu_tools;         reset; echo; header; break;;
			[sS]) echo -e "\033[1m${CMD_CHOSEN_SHELL}\033[0m";         echo; bash -login;           reset; echo; header; break;;
			[cC]) echo -e "\033[1m${CMD_CHOSEN_SETUP_BASE}\033[0m";    echo; submenu_setup_base;    reset; echo; header; break;;
			[pP]) echo -e "\033[1m${CMD_CHOSEN_SETUP_PLUGINS}\033[0m"; echo; submenu_setup_plugins; reset; echo; header; break;;
			[rR]) echo -e "\033[1m${CMD_CHOSEN_REBOOT}\033[0m";        echo; submenu_reboot;        reset; echo; header; break;;
			[xX]) echo -e "\033[1m${CMD_CHOSEN_SHUTDOWN}\033[0m";      echo; submenu_shutdown;      reset; echo; header; break;;
			[dD]) echo -e "\033[1m${CMD_CHOSEN_DEBUG}\033[0m";         echo; submenu_debug;         reset; echo; header; break;;
			[qQ]) echo -e "\033[1m${CMD_CHOSEN_QUIT}\033[0m";          echo; exit 0;;
		esac

		if [[ $found == true ]]; then
			break
		fi
	done
}

echo

if [ `id -u` = 0 ]; then

	header

	# Interactive mode for root
	while true; do menu; done

else
	exec bash -login
fi
