#!/bin/sh

# This script set a specific grub entry (winLOOSE…) for the next boot.
# Then reboot the host (by default) or just poweroff (if requested).

# Vars {{{
readonly PROGNAME=$(basename "${0}")
readonly PROGDIR=$(readlink -m $(dirname "${0}"))
readonly ARGS="${*}"
readonly NBARGS="${#}"

## Debug mode to print specific messages
DEBUG=1

## Grub specific vars
readonly GRUB_DEFAULT_PATH='/etc/default/grub'
readonly GRUB_DEFAULT_DIR='/etc/default/grub.d'
readonly WIN_GRUB="2"

## By default, the host should reboot at the end of the script
REBOOT=0
HALT=1

## Colors
readonly PURPLE='\033[1;35m'
readonly RED='\033[0;31m'
readonly RESET='\033[0m'
readonly COLOR_DEBUG="${PURPLE}"

# }}}

usage() {                                                       # {{{

	cat <<- EOF
usage: $PROGNAME [-d,--debug|-h,--help|--halt,--poweroff|--reboot]

Try to set a specific grub's entry for the next boot and
reboot the host (default behaviour).

EXAMPLES :
    - Set the grub entry ${WIN_GRUB} (Windows by default) and reboot
        ${PROGNAME}

    - Set the grub entry ${WIN_GRUB} (Windows by default) and shutdown
        ${PROGNAME} --halt

OPTIONS :
    -d,--debug
        Enable debug messages.

    -h,--help
        Print this help message.

    --halt,--poweroff
        Ask to shutdown at the end of the script.

    --reboot
        Ask to reboot at the end of the script (default behaviour).
EOF

}
# }}}
debug_message() {                                               # {{{

	local_debug_message="${1}"

	## Print message if DEBUG is enable (=0)
	[ "${DEBUG}" -eq "0" ] && printf '\e[1;35m%-6b\e[m\n' "DEBUG − ${PROGNAME} : ${local_debug_message}"

}
# }}}
main() {                                                        # {{{

	# First check in Grub default dir if saved mode is set
	if grep -q -E -R -- "^GRUB_DEFAULT=saved" "${GRUB_DEFAULT_DIR}"
	then
		debug_message "saved mode is enable in ${GRUB_DEFAULT_DIR} dir"

	# Second check the default grub file
	elif grep -q -E -- "^GRUB_DEFAULT=saved" "${GRUB_DEFAULT_PATH}"
	then
		debug_message "saved mode is enable in ${GRUB_DEFAULT_PATH} file"
	# Otherwise enable saved mode
	else
		printf '%b' "GRUB_DEFAULT is not set in 'saved' mode\n"
		debug_message "Enable grub saved mode in ${GRUB_DEFAULT_PATH} file"
		sudo sed -i 's/\(^GRUB_DEFAULT.*\)/#\1\nGRUB_DEFAULT=saved/' "${GRUB_DEFAULT_PATH}"

		GRUB_DEFAULT_ENTRY=$(grep -E -- "#GRUB_DEFAULT=" "${GRUB_DEFAULT_PATH}" | cut -d"=" -f2)

		## Set current GRUB_DEFAULT as default grub's entry
		##   Exit if fails
		sudo grub-set-default "${GRUB_DEFAULT_ENTRY}" \
			|| exit 1

		## Try to update grub's configuration
		##   Exit if fails
		sudo update-grub \
			|| exit 2
	fi

	printf '%b' "Reboot to windaube partition\\n"
	sudo grub-reboot "${WIN_GRUB}"
	[ "${REBOOT}" -eq "0" ] && sudo systemctl reboot
	[ "${HALT}" -eq "0" ] && sudo systemctl poweroff
}
# }}}

# Manage arguments                                                # {{{
# This code can't be in a function due to arguments

if [ ! "${NBARGS}" -eq "0" ]; then

	manage_arg="0"

	# Parse all options (start with a "-") one by one
	while printf -- '%s' "${1}" | grep -q -E -- "^-+"; do

	case "${1}" in
		-d|--debug )        ## debug
			DEBUG=0
			;;
		-h|--help )         ## help
			usage
			## Exit after help informations
			exit 0
			;;
		--halt|--poweroff ) ## A poweroff was requested
			REBOOT=1
			HALT=0
			;;
		--reboot )          ## A reboot was requested (default behaviour)
			REBOOT=0
			HALT=1
			;;
		-- )                ## End of options list
			## End the while loop
			break
			;;
		* )                 ## unknow option
			printf '%b\n' "${RED}Invalid option: ${1}${RESET}"
			printf '%b\n' "---"
			usage
			exit 1
			;;
	esac

	debug_message "Arguments management − \
${RED}${1}${COLOR_DEBUG} option managed."

	## Move to the next argument
	shift
	manage_arg=$((manage_arg+1))

	done

	debug_message "Arguments management − \
${RED}${manage_arg}${COLOR_DEBUG} argument(s) successfully managed."
else
	debug_message "Arguments management − \
No arguments/options to manage."
fi

# }}}

main

exit 0
