#!/usr/bin/bash

source /usr/share/Navix-WSL/0-functions

grep -q "release 9" /etc/redhat-release 2>/dev/null
(( $? == 0 )) && is_rhel9=1

# {{{ function help ()
function help {
	cat <<-EOL
		${bwhite}Usage:${normal} systemd-wsl [command]
		${bwhite}Description:${normal} Enable, disable, or check the status of systemd in WSL (Windows Subsystem for Linux).
		${bwhite}Options:${normal}
		          ${bwhite}-h, --help${normal}    Show this help message and exit
		          ${bwhite}-v, --verbose${normal} Enable verbose output
		${bwhite}Commands${normal}:
		          ${bwhite}on${normal}            Enable systemd in WSL
		          ${bwhite}off${normal}           Disable systemd in WSL
		          ${bwhite}status${normal}        Show systemd status in WSL

	EOL

	exit 1
}
# }}}

# {{{ function do-cmd (command)
function do-cmd {
	local sudocmd cmd
	local debug=0
	local i

	debug=${verbose}
	(( dry == 1 ))&& verbose=1
	(( verbose_off == 1 )) && debug=0

	for i in "${@}"
	do
		grep -Eq '[[:space:]]' <<< "${i}"
		(( $? == 0 )) && cmd+=" \"${i}\"" || cmd+=" ${i}"
	done

	(( UID != 0 )) && sudocmd="sudo "
	(( debug == 1 )) && echo "${bcyan}** ==> ${sudocmd}${cmd}${normal}"
	eval ${sudocmd}${cmd}
	return $?
}
# }}}

# {{{ function remove_wlsconf_entries ()
function remove_wlsconf_entries {
	do-cmd sed -ri '/\[boot\]/d' "${wslconf}" 2> /dev/null
	do-cmd sed -ri '/systemd[[:space:]]*=.*/d' "${wslconf}" 2> /dev/null
}
# }}}

# {{{ function enable_systemd ()
function enable_systemd {
	local tmpfile="/tmp/systemd-wsl.$$"
	(( is_enable == 1 )) && {
		echo "Systemd startup configuaration is ${byellow}already set${normal} to enabled in WSL."
		exit 0
	}

	if (( is_set == 1 )); then
		do-cmd sed -ri 's/systemd[[:space:]]*=.*/systemd=true/' "${wslconf}"
	else
		remove_wlsconf_entries
		fsize="$( stat -c %s "${wslconf}" 2>/dev/null )"
		if [[ -f ${wslconf} && ${fsize} -gt 1 ]]; then
			do-cmd sed -ri '1i [boot]\nsystemd=true\n' "${wslconf}"
		else
			verbose_off=1 do-cmd cat <<-EOL > "${tmpfile}"
				[boot]
				systemd=true
			EOL
			[[ -f ${tmpfile} ]] && {
				do-cmd mv "${tmpfile}" "${wslconf}"
				(( UID != 0 )) && do-cmd chown root:root "${wslconf}"
			}
		fi
	fi

	ls -al /etc/systemd/system/systemd-logind.service 2>/dev/null | grep -q -- '-> /dev/null'
	(( $? == 0 )) &&
		do-cmd rm -f /etc/systemd/system/systemd-logind.service

	check_status
	if (( is_enable != 1 )); then
		echo "${bred}[ERROR]${normal} Failed to enable systemd in WSL."
		exit 1
	fi
	cat <<-EOL
		Systemd has been ${bgreen}enabled${normal} in WSL. Please ${byellow}restart${normal} your WSL instance.

		    🔄 ${shutdown_command}
		    🔄 wsl -d ${WSL_DISTRO_NAME}

	EOL
}
# }}}

# {{{ function disable_systemd ()
function disable_systemd {
	(( is_enable == 0 )) && {
		echo "Systemd startup configuration is ${byellow}already set${normal} to disabled in WSL."
		exit 0
	}

	(( is_set == 1 )) &&
		do-cmd sed -ri 's/systemd[[:space:]]*=.*/systemd=false/' "${wslconf}"
	check_status

	if (( is_enable == 1 )); then
		echo "${bred}[ERROR]${normal} Failed to disable systemd in WSL."
		exit 1
	fi
	cat <<-EOL
		Systemd has been ${bcyan}disabled${normal} in WSL. Please ${byellow}restart${normal} your WSL instance.

		    🔄 ${shutdown_command}
		    🔄 wsl -d ${WSL_DISTRO_NAME}

	EOL
}
# }}}

# {{{ function status_systemd ()
function status_systemd {
	local imogi=( "❌" "✅")

	cat <<-EOL
		📊 ${bmagenta}Systemd status in WSL${normal}

		    ${imogi[run]} Systemd is currently running
		    ${imogi[is_enable]} Systemd enabled in wsl.conf

	EOL

	(( is_rhel9 == 1 )) && {
		cat <<-EOL
			In WSL2, when using systemd of RHEL9 series including Navix 9,
			the wsl -t command may cause an incomplete shutdown of systemd-logind.
			Therefore, please use the wsl --shutdown command instead of wsl -t,
			or use the shutdown now command on the WSL Linux OS to shut down the system.

			${byellow}In conclusion${normal},
			do not use ${bred}wsl -t${normal} to terminate,

			but use for shutdown commands such as:

			🔄 ${bcyan}wsl --shutdown${normal} or
			🔄 ${bgreen}shell>${normal} ${bwyite}shutdown now${normal}

		EOL
	}

	(( is_enable == 1 )) && return 0 || return 1
}
# }}}

# {{{ function check_status ()
function check_status {
	[[ -z ${run} ]] && {
		[[ ! -f /usr/bin/pidof ]] &&
			do-cmd dnf -y install procps-ng 2>/dev/null >& /dev/null

		pidof systemd >& /dev/null
		(( $? == 0 )) && run=1 || run=0
	}

	grep -q "^[[:space:]]*systemd[[:space:]]*=" ${wslconf} 2>/dev/null
	(( $? == 0 )) && is_set=1 || is_set=0
	grep -q "^[[:space:]]*systemd[[:space:]]*=[[:space:]]*true" ${wslconf} 2>/dev/null
	(( $? == 0 )) && is_enable=1 || is_enable=0
}
# }}}

# {{{ getopt parsing
verbose=0
wslconf="/etc/wsl.conf"
sopt="c:htv"
longopts="conf:,dry-run,help,verbose"
opts="$( getopt -o ${sopt} -l ${longopts} -n 'systemd-wsl' -- "${@}" )"
(( $? != 0 )) && help

eval set -- "${opts}"
for opt
do
	case "${opt}" in
		-c|--conf)
			wslconf="${2}"
			[[ ! -f ${wslconf} ]] && {
				echo "${bred}[ERROR]${normal} The specified wsl.conf file '${wslconf}' does not exist."
				exit 1
			}
			shift 2
			;;
		-t|--dry-run)
			dry=1
			shift
			;;
		-h|--help)
			help
			;;
		-v|--verbose)
			verbose=1
			shift
			;;
		--)
			shift
			break
			;;
	esac
done
# }}}

#(( $UID != 0 )) && {
#	echo "Please run as root or use sudo."
#	exit 1
#}

(( dry == 1 )) && {
	# In dry-run mode, to avoid making actual changes, change the configuration
	# file to a temporary file. This prevents the do-cmd function from making
	# actual changes to the file. This temporary file will be deleted upon script
	# exit.
	tmp_wslconf="/tmp/systemd-wsl-wslconf.$$"
	cp -f "${wslconf}" "${tmp_wslconf}"
	wslconf="${tmp_wslconf}"
	trap "[[ -f ${tmp_wslconf} ]] && rm -f ${tmp_wslconf}" EXIT
}

pidof systemd >& /dev/null
(( $? == 0 )) && run=1 || run=0

if (( is_rhel9 == 1 )); then
	shutdown_command="wsl --shutdown"
	(( run == 1 )) &&
		shutdown_command+=" or ${bgreen}shell>${normal} systermctl poweroff"
else
	shutdown_command="wsl -t ${WSL_DISTRO_NAME}"
fi

check_status

case "$1" in
	on)
		enable_systemd
		;;
	off)
		disable_systemd
		;;
	status)
		status_systemd
		;;
	*)
		help
		;;
esac

exit $?

# vim: filetype=sh noet si sw=4 ts=4 fdm=marker
