#!/sbin/openrc-run

# conf.d may replace PATH for provider CLIs. Restore OpenRC's own helpers;
# supervise-daemon removes these internal directories from the child's PATH.
export PATH="${RC_LIBEXECDIR:-/usr/libexec/rc}/bin:${RC_LIBEXECDIR:-/usr/libexec/rc}/sbin:/usr/sbin:/sbin:$PATH"

name="T3 Code"
description="RTVision T3 Code server"
supervisor=supervise-daemon
command="${t3code_node:-/usr/bin/node}"
command_user="${t3code_user:-}"
directory="${t3code_home:-}"
export HOME="${t3code_home:-}"
export T3CODE_HOME="${T3CODE_HOME:-${t3code_home:-}/.t3}"
export T3CODE_NO_BROWSER=1
command_args="\"$T3CODE_HOME/runtime/service-launcher.mjs\""
pidfile="/run/$RC_SVCNAME.pid"
output_log="/var/log/t3code/$RC_SVCNAME.log"
error_log="$output_log"
respawn_delay=5
respawn_max=5
respawn_period=300
# Let the launcher finish an update transition before forced shutdown.
retry="TERM/120/KILL/5"
umask=0022

depend() {
	need localmount
	use net
}

_configure_tea() {
	[ -n "${T3CODE_GITEA_TOKEN:-}" ] || return 0
	local config_home="$1" temp_file
	checkpath --directory --mode 0755 --owner root:root \
		"$config_home" "$config_home/tea" || return 1
	temp_file=$(mktemp "$config_home/tea/.config.XXXXXX") || return 1
	# JSON is valid YAML. Use Node to quote the token and validate the same
	# web-root URL accepted by T3, including ports and proxy subpaths.
	if ! /usr/bin/node -e '
		try {
			const url = new URL(process.env.T3CODE_GITEA_BASE_URL);
			if (!["http:", "https:"].includes(url.protocol) ||
				url.username || url.password || url.search || url.hash) {
				throw new Error();
			}
			process.stdout.write(JSON.stringify({logins: [{
				name: "t3code", url: url.href.replace(/\/+$/, ""),
				token: process.env.T3CODE_GITEA_TOKEN, default: true,
				version_check: false
			}]}));
		} catch {
			console.error("Set T3CODE_GITEA_BASE_URL to the Gitea web root");
			process.exitCode = 1;
		}
	' >"$temp_file"; then
		rm -f "$temp_file"
		return 1
	fi
	if ! checkpath --file --mode 0600 --owner "$command_user" "$temp_file" ||
		! mv -f "$temp_file" "$config_home/tea/config.yml"; then
		rm -f "$temp_file"
		return 1
	fi
	export T3CODE_TEA_CONFIG_HOME="$config_home"
	export PATH="/usr/libexec/t3code:$PATH"
}

start_pre() {
	if [ -z "$command_user" ] || [ "$command_user" = root ] ||
		[ "$(id -u "$command_user" 2>/dev/null)" = 0 ]; then
		eerror "Set t3code_user to a non-root account in /etc/conf.d/$RC_SVCNAME"
		return 1
	fi
	if ! id "$command_user" >/dev/null 2>&1; then
		eerror "T3 account does not exist: $command_user"
		return 1
	fi
	case "$directory:$T3CODE_HOME" in
	/*:/*) ;;
	*) eerror "t3code_home and T3CODE_HOME must be absolute paths"; return 1 ;;
	esac
	# OpenRC evaluates command arguments. Keep service paths unambiguous.
	case "$directory$T3CODE_HOME$command" in
	*[!a-zA-Z0-9_./-]*)
		eerror "Service paths may only contain letters, numbers, _, ., / and -"
		return 1 ;;
	esac
	if [ ! -d "$directory" ] || [ ! -x "$command" ] ||
		[ ! -r "$T3CODE_HOME/runtime/service-launcher.mjs" ] ||
		[ ! -r "$T3CODE_HOME/runtime/service-state.json" ]; then
		eerror "Prepare the runtime as $command_user with t3code-prepare first"
		return 1
	fi
	# Resolve saved agent sockets when Git connects, including after login.
	if [ -z "${GIT_SSH:-}" ]; then
		export GIT_SSH=/usr/libexec/t3code/git-ssh/ssh
	fi
	if [ -n "${T3CODE_GITEA_TOKEN:-}" ]; then
		checkpath --directory --mode 0755 --owner root:root /run/t3code ||
			return 1
		_configure_tea "/run/t3code/$RC_SVCNAME" || return 1
	fi
	# supervise-daemon opens logs after dropping to the service account.
	checkpath --directory --mode 0755 --owner root:root /var/log/t3code ||
		return 1
	checkpath --file --mode 0600 --owner "$command_user" "$output_log"
}
