#!/bin/zsh
setopt no_unset extended_glob warn_create_global

# helpers
die() {
	printf >&2 '%s\n' "$@"
	exit 1
}

ensure-container-started() {
	[[ $1 == */* ]] && die "Invalid container name: ${(qqq)1}"
	s6-svc -wU -T 4000 -o /run/service/container.$1 || die "failed to start container ${(qqq)1}"
}

cmd_up() {
	local name
	for name in "$@"; do
		ensure-container-started $name
	done
}
typeset -f -t cmd_up

cmd_down() {
	local name
	for name in "$@"; do
		[[ $name == */* ]] && die "Invalid container name: ${(qqq)name}"
		s6-svc -wd -T 1000 -d /run/service/container.$name || \
			s6-svc -wd -T 1000 -dk /run/service/container.$name
	done
}
typeset -f -t cmd_down

cmd_link() {
	local old new relpath

	[[ $1 == */* ]] && die "Invalid container name: ${(qqq)1}"
	old=$1

	[[ $2 == */* ]] && die "Invalid container name: ${(qqq)2}"
	new=$2

	shift 2 || exit $?
	for relpath in "$@"; do
		[[ $relpath == /* ]] && die "Invalid relpath: ${(qqq)relpath}"
		[[ $PWD/$relpath != ${relpath:a} ]] && die "Invalid relpath: ${(qqq)relpath}"
	done
	ensure-container-started $old
	ensure-container-started $new
	link-to-container-inbox $old $new "$@" || exit $?
}
typeset -f -t cmd_link

cmd_services() {
	local -a args
	local c s
	while (($#)); do
		case $1 in
			(-o)
				args+=( $1 $2 )
				shift 2 || exit $?
				;;
			(-*)
				args+=( $1 )
				shift || exit $?
				;;
			(*)
				die "non_whitelisted argument: ${(qqq)1}"
				;;
		esac
	done
	for c in /run{,/user/$UID}/service/*/supervise/control(pN); do
		s=${c:h:h}
		printf '%s\t' $s
		s6-svstat "$args[@]" $s
	done
}

main() {
	[[ $# -gt 0 ]] || die "xsession-cmd: argument required"
	local cmd=$1
	shift
	if (($+functions[cmd_$cmd])); then
		cmd_$cmd "$@" || die "command failed: ${(qqq)cmd}"
	else
		die "unknown command: ${(qqq)cmd}"
	fi
}

main "$@"