#!/bin/sh

set -e

PROGNAME=Xsession

OPTIONFILE=/etc/X11/Xsession.options

[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/X11/xresources" ] && USRRESOURCES=${XDG_CONFIG_HOME:-$HOME/.config}/X11/xresources || USRRESOURCES=$HOME/.Xresources
[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/X11/xsession.d" ] && SESSIONDIR=${XDG_CONFIG_HOME:-$HOME/.config}/X11/xsession.d || SESSIONDIR=/etc/X11/Xsession.d
[ -d "${XDG_DATA_HOME:-$HOME/.local/share}/xorg/" ] && ERRFILE=${XDG_DATA_HOME:-$HOME/.local/share}/xorg/xsession-errors || ERRFILE=$HOME/.xsession-errors

message() {
	# pretty-print messages of arbitrary length; use xmessage if it
	# is available and $DISPLAY is set
	MESSAGE="$PROGNAME: $*"
	echo "$MESSAGE" | fold -s -w ${COLUMNS:-80} >&2
	# if [ -n "$DISPLAY" ] && command -v xmessage > /dev/null 2>&1; then
	#   echo "$MESSAGE" | fold -s -w ${COLUMNS:-80} | xmessage -center -file -
	# fi
}

message_nonl() {
	# pretty-print messages of arbitrary length (no trailing newline); use
	# xmessage if it is available and $DISPLAY is set
	MESSAGE="$PROGNAME: $*"
	echo -n "$MESSAGE" | fold -s -w ${COLUMNS:-80} >&2
	# if [ -n "$DISPLAY" ] && command -v xmessage > /dev/null 2>&1; then
	#   echo -n "$MESSAGE" | fold -s -w ${COLUMNS:-80} | xmessage -center -file -
	# fi
}

errormsg() {
	# exit script with error
	message "$*"
	exit 1
}

internal_errormsg() {
	# exit script with error; essentially a "THIS SHOULD NEVER HAPPEN" message
	# One big call to message() for the sake of xmessage; if we had two then
	# the user would have dismissed the error we want reported before seeing the
	# request to report it.
	errormsg "$*" \
		"Please report the installed version of the \"x11-common\"" \
		"package and the complete text of this error message to" \
		"<debian-x@lists.debian.org>."
}

OPTIONS="$(
	if [ -r "$OPTIONFILE" ]; then
		cat "$OPTIONFILE"
	fi
	if [ -d /etc/X11/Xsession.options.d ]; then
		run-parts --list --regex '\.conf$' /etc/X11/Xsession.options.d | xargs -d '\n' cat
	fi
)"

has_option() {
	# Ensure that a later no-foo overrides an earlier foo
	if [ "$(echo "$OPTIONS" | grep -Eo "^(no-)?$1\>" | tail -n 1)" = "$1" ]; then
		return 0
	else
		return 1
	fi
}

# attempt to create an error file; abort if we cannot
if (umask 077 && touch "$ERRFILE") 2>/dev/null && [ -w "$ERRFILE" ] &&
	[ ! -L "$ERRFILE" ]; then
	chmod 600 "$ERRFILE"
elif ERRFILE=$(mktemp 2>/dev/null); then
	if ! ln -sf "$ERRFILE" "${TMPDIR:=/tmp}/xsession-$USER"; then
		message "warning: unable to symlink \"$TMPDIR/xsession-$USER\" to" \
			"\"$ERRFILE\"; look for session log/errors in" \
			"\"$TMPDIR/xsession-$USER\"."
	fi
else
	errormsg "unable to create X session log/error file; aborting."
fi

# truncate ERRFILE if it is too big to avoid disk usage DoS
if [ "$(stat -c%s \""$ERRFILE"\")" -gt 500000 ]; then
	T=$(mktemp -p "$HOME")
	tail -c 500000 "$ERRFILE" >"$T" && mv -f "$T" "$ERRFILE" || rm -f "$T"
fi

exec >>"$ERRFILE" 2>&1

# sanity check; is our session script directory present?
if [ ! -d "$SESSIONDIR" ]; then
	errormsg "no \"$SESSIONDIR\" directory found; aborting."
fi

# Attempt to create a file of non-zero length in /tmp; a full filesystem can
# cause mysterious X session failures.  We do not use touch, :, or test -w
# because they won't actually create a file with contents.  We also let standard
# error from mktemp and echo go to the error file to aid the user in
# determining what went wrong.
WRITE_TEST=$(mktemp)
if ! echo "*" >>"$WRITE_TEST"; then
	message "warning: unable to write to ${WRITE_TEST%/*}; X session may exit" \
		"with an error"
fi
rm -f "$WRITE_TEST"

SESSIONFILES=$(run-parts --list $SESSIONDIR)
if [ -n "$SESSIONFILES" ]; then
	set +e
	for SESSIONFILE in $SESSIONFILES; do
		message "Executing $SESSIONFILE"
		. $SESSIONFILE
	done
	set -e
fi

if [ -f "${XDG_CONFIG_HOME:-$HOME/.config}/X11/xprofile" ]; then
	. ${XDG_CONFIG_HOME:-$HOME/.config}/X11/xprofile
else
	. $HOME/.xprofile
fi

exec dwm