#!/bin/sh

show_help() {
	cat <<EOF
Usage: $0 <subcommand>

SUBCOMMANDS

run-desktop
	Starts the foxclient desktop for the current user.

run-desktop-inner
	Internally used by run-desktop, don't use.

start|stop|restart|status <service> [<args...>]
	Subcommands for managing foxclient services.

exit
	Will cause foxde to shut down all services and then exit.

hook <hook> [<args...>]
	Trigger foxclient hooks of a given type.
	Arguments are hook specific.

ls-sv
	List available foxclient services

ls-hook
	List available foxclient hooks

ENVIRONMENT VARIABLES

XDG_RUNTIME_DIR
	An XDG_RUNTIME_DIR is needed for foxclient to store temporary files.

FOXCLIENT_PROFILE
	Point to a directory where the profile configuration is stored.
EOF
}


FOXCLIENT_PROFILE="${FOXCLIENT_PROFILE:-/usr/share/foxclient-default-profile}"
FOXCLIENT_RUNTIME_DIR="${FOXCLIENT_RUNTIME_DIR:-$XDG_RUNTIME_DIR/foxclient}"
FOXCLIENT_PIDFILE="$FOXCLIENT_RUNTIME_DIR/runsvdir.pid"

FOXCLIENT_SV="$FOXCLIENT_RUNTIME_DIR/sv"
export SVDIR="$FOXCLIENT_SV"

assert_expected_environment() {
	if [ -z "$XDG_RUNTIME_DIR" ] ; then
		echo "Foxclient requires an XDG_RUNTIME_DIR!" >&2
		exit 1
	fi
}

assert_foxclient_profile() {
	if ! [ -d "$FOXCLIENT_PROFILE" ] ; then
		echo "No foxclient profile active." >&2
		echo "Check the FOXCLIENT_PROFILE environment variable."
		exit 1
	fi
}



run_desktop() {
	mkdir -p "$FOXCLIENT_RUNTIME_DIR"
	trap stop_running TERM
	trap stop_running INT
	# Run in backgroudn and wait to no block the traps we just registred
	flock -x --nonblock -E 123 -- "$FOXCLIENT_RUNTIME_DIR" "$0" run-desktop-inner &
	wait "$!"
	EXIT_CODE="$?"
	case "$EXIT_CODE" in
		123)
			echo "Foxclient is already running!" >&2
			;;
		*)
			;;
	esac
	rm -r "$FOXCLIENT_RUNTIME_DIR"
	exit $EXIT_CODE
}

run_desktop_inner() {
	mkdir -p "$FOXCLIENT_SV"
	rsync --delete -r "$FOXCLIENT_PROFILE/sv/" "$FOXCLIENT_SV/"
	runsvdir "$FOXCLIENT_SV" &
	RUNSVDIR_PID="$!"
	"$0" hook startup &
	trap stop_running TERM
	trap stop_running INT
	trap cleanup_pidfile EXIT
	echo "$RUNSVDIR_PID" > "$FOXCLIENT_PIDFILE"
	wait "$RUNSVDIR_PID"
}

stop_running() {
	PID="$(head -n 1 "$FOXCLIENT_PIDFILE")"
	kill -s HUP "$PID"
}

cleanup_pidfile() {
	if [ -f "$FOXCLIENT_PIDFILE" ] ; then
		rm "$FOXCLIENT_PIDFILE"
	fi
}

SUBCOMMAND="$1"
case "$SUBCOMMAND" in
	run-desktop)
		assert_expected_environment
		assert_foxclient_profile
		run_desktop
		;;
	run-desktop-inner)
		assert_expected_environment
		assert_foxclient_profile
		run_desktop_inner
		;;
	start|restart|stop|status)
		if ! printf "%s" "$2" | grep -qE '^[A-Za-z0-9_-]+$' ; then
			echo "Invalid service name, must match [A-Za-z0-9_-]+ ." >&2
			exit 1
		fi
		exec sv "$@"
		;;
	exit)
		assert_expected_environment
		stop_running
		;;
	hook)
		assert_expected_environment
		HOOK="$2"
		shift 1
		if ! printf "%s" "$HOOK" | grep -qE '^[A-Za-z0-9_-]+$' ; then
			echo "Invalid hook name, must match [A-Za-z0-9_-]+ ." >&2
			exit 1
		fi
		if ! [ -d "$FOXCLIENT_PROFILE/hooks/$HOOK" ] ; then
			echo "No hooks registred as '$HOOK'"
		fi
		for script in "$FOXCLIENT_PROFILE/hooks/$HOOK"/* ; do
			"$script" "$@"
		done
		;;
	ls-sv)
		assert_expected_environment
		ls "$FOXCLIENT_SV"
		;;
	ls-hook)
		assert_expected_environment
		ls "$FOXCLIENT_PROFILE/hooks"
		;;
	help|--help)
		show_help
		;;
	"")
		echo "Usage: $0 <subcommand>" >&2
		echo "See $0 --help for more information." >&2
		exit 1 ;;
	*)
		echo "Unknown subcommand: '$1'" >&2
		echo "See $0 --help for available subcommands." >&2
		exit 1 ;;
esac
