#!/bin/sh
# Authors: akdengi, 2013; mikhailnov (Mikhail Novosyolov), 2018

# we have to assume that "$SYSCONFIG_DESKTOP_FILE" has two variables, DESKTOP
# and DISPLAYMANAGER because administors may prefer a specific DM regardless
# of desktops.
# DISPLAYMANAGER is referenced by this script, and DESKTOP is referenced
# as system-wide default by /etc/X11/Xsession script only when X-session
# is opened by "startx" command. 
# when DMs open an X-session, they send DESKTOP, which is in this case
# directly selected by users, as a commandline argument of /etc/X11/Xsession.
# actually Xsession script is only able to know by existance of its first
# argument whether it is called by DM or "startx". see the logic
# in /etc/X11/Xsession.
# If DISPLAYMANAGER is not defined, then assume that it is the same as DESKTOP

dm_service=''
# SYSCONFIG_DESKTOP_FILE can be overriden via environmental variable
SYSCONFIG_DESKTOP_FILE="${SYSCONFIG_DESKTOP_FILE:-/etc/sysconfig/desktop}"
PKG_SYSTEM="${PKG_SYSTEM:-RPM}"
PKG_INSTALL_CMD="${PKG_INSTALL_CMD:-urpmi}"

if [ "$(id -u)" != "0" ]; then
	echo_err "Run this script as root!"
	exit 1
fi

# check that we are using systemd
if [ -z "$(ps aux | grep -q systemd)" ] && [ ! -x "$(which systemctl)" ] && [ ! -x "$(which loginctl)" ] && [ ! -x "$(which systemd-run)" ]; then
	echo "This system does not use systemd. Cannot set display manager. Exiting."
	exit 1
fi

echo_help(){
	echo "Usage: set|set_new_dm, restart|restart_session"
	echo "set|set_new_dm applies variables from ${SYSCONFIG_DESKTOP_FILE}, restart|restart_session stops the current DM and starts the new one."
}

exit_var_error(){
	echo "Variable DISPLAYMANAGER in either config file ${SYSCONFIG_DESKTOP_FILE} or as an environmental variable is ${1}."
	echo "We cannot continue working. Exiting."
	exit 1
}

load_config(){
	# read and respect environmental variables
	if [ -z "$DISPLAYMANAGER" ] || [ -z "$DESKTOP" ]; then 
		[ -f "$SYSCONFIG_DESKTOP_FILE" ] && \
		. "$SYSCONFIG_DESKTOP_FILE" >/dev/null 2>&1
	fi
	if [ -z "$DISPLAYMANAGER" ] && [ ! -z "$DESKTOP" ]; then
		DISPLAYMANAGER="$DESKTOP"
	fi

	# exit with error if DISPLAYMANAGER still has not been set
	if [ -z "$DISPLAYMANAGER" ]; then
		exit_var_error 'not set'
	fi
		
	# convert all upper-case letters to low-case
	#DISPLAYMANAGER="${DISPLAYMANAGER,,}" # This is non-POSIX, let's not use it
	DISPLAYMANAGER="$(echo "$DISPLAYMANAGER" | tr '[:upper:]' '[:lower:]')"
	case "$DISPLAYMANAGER" in
		'gdm' | 'gnome' | 'gnome3' ) dm_service='gdm' ;;
		'kdm' | 'kde4' | 'kde' ) dm_service='kdm' ;;
		'sddm' | 'kde5' | 'plasma5' | 'plasma' ) dm_service='sddm' ;;
		'slim' ) dm_service='slim' ;;
		'lightdm' ) dm_service='lightdm' ;;
		'xdm' ) dm_service='xdm' ;;
		* ) 
			exit_var_error 'incorrect'
		;;
	esac
}

set_new_dm(){
	# Disable display-mananger.service symlink and enable preffered dm
	# check if /etc/systemd/system/display-manager.service is a symlink; otherwise we must not delete it
	if readlink /etc/systemd/system/display-manager.service ; then
		rm -f /etc/systemd/system/display-manager.service
	fi

	if ! systemctl -q enable "${dm_service}.service"; then
		echo "Error enabling systemd service ${dm_service}.service!"
		if [ ! -f "$(systemctl cat display-manager.service | head -n 1 | awk -F '# ' '{print $2}')" ]
			then
				echo "systemd service file does not exist."
				case "$PKG_SYSTEM" in
					'RPM' )
						if ! rpm -q "${dm_service}" >/dev/null 2>&1 ; then
							echo "Package ${dm_service} is not installed. Install it: ${PKG_INSTALL_CMD} ${dm_service}"
						fi
					;;
					* ) echo "Defined packaging system ${PKG_SYSTEM} is not supported." ;;
				esac
			else
				:
		fi
		exit 1
	fi

	case "$dm_service" in
		'gdm' ) alt_bin='/usr/lib/gdm/gdmflexiserver' ;;
		'lightdm' ) alt_bin='/usr/lib/lightdm/gdmflexiserver' ;;
	esac

	if [ ! -z "$alt_bin" ] && [ -x "$(which update-alternatives)" ]; then
		if update-alternatives --set gdmflexiserver "$alt_bin"
			then exit 0
			else
				echo "update-alternatives failed"
				exit 1
		fi
	fi
}

restart_session(){
	current_dm="$(loginctl show-session "$XDG_SESSION_ID" | grep '^Service=' | awk -F '=' '{print $NF}' | sort | uniq | tr '\n' ' ')"
	export current_dm
	export dm_service
	if [ ! -z "$current_dm" ] && [ ! -z "$dm_service" ]
		then
			# See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=825394 to understand why we use systemd-run
			systemd-run \
				--setenv=current_dm="$current_dm" \
				--setenv=dm_service="$dm_service" \
				--scope nohup sh -c "systemctl stop ${current_dm}; systemctl start ${dm_service}"
		else
			echo "Error restarting DM: some variables are empty."
			exit 1
	fi
}

load_config

case "$1" in
	'set' | 'set_new_dm' ) set_new_dm ;;
	'restart' | 'restart_session' ) restart_session ;;
	* ) echo_help ;;
esac
