#!/bin/sh
set -eu

download_base=${EDGEGUARD_AGENT_DOWNLOAD_BASE:-https://agent.eg.stgon.cloud}
release_channel=${EDGEGUARD_AGENT_CHANNEL:-v0.1.4}

die() {
	printf 'EdgeGuard Agent installer: %s\n' "$*" >&2
	exit 1
}

[ "$(id -u)" -eq 0 ] || die "run as root (curl -fsSL $download_base/install.sh | sudo bash)"
[ "$(uname -s)" = Linux ] || die "only Linux is supported"

case "$(uname -m)" in
	x86_64 | amd64) architecture=x86_64 ;;
	aarch64 | arm64) architecture=aarch64 ;;
	*) die "unsupported architecture: $(uname -m)" ;;
esac

distro=unknown
if [ -r /etc/os-release ]; then
	# shellcheck disable=SC1091
	. /etc/os-release
	distro=${ID:-unknown}
fi

if command -v systemctl >/dev/null 2>&1 && [ -d /run/systemd/system ]; then
	init_system=systemd
elif command -v rc-update >/dev/null 2>&1 && [ -x /sbin/openrc-run ]; then
	init_system=openrc
else
	die "neither a running systemd nor OpenRC installation was found"
fi

if command -v curl >/dev/null 2>&1; then
	download() { curl --proto '=https' --tlsv1.2 -fsSL "$1" -o "$2"; }
elif command -v wget >/dev/null 2>&1; then
	download() { wget -q "$1" -O "$2"; }
else
	die "curl or wget is required"
fi
command -v sha256sum >/dev/null 2>&1 || die "sha256sum is required"

work_dir=$(mktemp -d /tmp/edgeguard-agent-install.XXXXXX)
cleanup() {
	case "$work_dir" in
		/tmp/edgeguard-agent-install.*) find "$work_dir" -xdev -depth -delete ;;
	esac
}
trap cleanup EXIT HUP INT TERM

verify_file() {
	checksums=$1
	file=$2
	name=$3
	expected=$(awk -v name="$name" '$2 == name || $2 == "./" name { print $1; exit }' "$checksums")
	case "$expected" in
		*[!0-9a-fA-F]* | '') die "checksum is missing or invalid for $name" ;;
	esac
	[ "${#expected}" -eq 64 ] || die "checksum has an invalid length for $name"
	actual=$(sha256sum "$file" | awk '{ print $1 }')
	[ "$actual" = "$expected" ] || die "checksum verification failed for $name"
}

artifact_base=$download_base/$release_channel/$architecture
template_base=$download_base/$release_channel/templates/$init_system
printf 'Installing EdgeGuard Agent for %s/%s (%s)...\n' "$distro" "$architecture" "$init_system"

download "$artifact_base/edgeguard-agent" "$work_dir/edgeguard-agent"
download "$artifact_base/SHA256SUMS" "$work_dir/binary-SHA256SUMS"
verify_file "$work_dir/binary-SHA256SUMS" "$work_dir/edgeguard-agent" edgeguard-agent

if [ "$init_system" = systemd ]; then
	templates='edgeguard-agent-tunnel.service edgeguard-agent-tunnel.path edgeguard-agent-report.service edgeguard-agent-report.timer'
else
	templates='edgeguard-agent.initd edgeguard-agent-report'
fi
download "$template_base/SHA256SUMS" "$work_dir/template-SHA256SUMS"
for template in $templates; do
	download "$template_base/$template" "$work_dir/$template"
	verify_file "$work_dir/template-SHA256SUMS" "$work_dir/$template" "$template"
done

install -d -m 0755 /usr/bin
install -d -m 0700 /var/lib/edgeguard-agent
install -m 0755 "$work_dir/edgeguard-agent" /usr/bin/edgeguard-agent

if [ "$init_system" = systemd ]; then
	install -d -m 0755 /etc/systemd/system
	for template in $templates; do
		install -m 0644 "$work_dir/$template" "/etc/systemd/system/$template"
	done
	systemctl daemon-reload
	systemctl enable --now edgeguard-agent-tunnel.path edgeguard-agent-report.timer >/dev/null
else
	install -d -m 0755 /etc/init.d /etc/periodic/15min
	install -m 0755 "$work_dir/edgeguard-agent.initd" /etc/init.d/edgeguard-agent
	install -m 0755 "$work_dir/edgeguard-agent-report" /etc/periodic/15min/edgeguard-agent-report
	rc-update add edgeguard-agent default >/dev/null
fi

if [ "${EDGEGUARD_AGENT_INSTALL_ONLY:-0}" = 1 ]; then
	printf '%s\n' 'EdgeGuard Agent files installed and verified (enrollment skipped).'
	exit 0
fi

origin_url=${EDGEGUARD_AGENT_ORIGIN_URL:-}
if [ -z "$origin_url" ]; then
	[ -r /dev/tty ] || die "no interactive terminal; set EDGEGUARD_AGENT_ORIGIN_URL"
	printf 'Local Origin URL (for example https://127.0.0.1:8080): ' >/dev/tty
	IFS= read -r origin_url </dev/tty || die "could not read the Origin URL"
fi
[ -n "$origin_url" ] || die "the Origin URL must not be empty"

/usr/bin/edgeguard-agent connect --origin-url "$origin_url"

if [ "$init_system" = systemd ]; then
	systemctl restart edgeguard-agent-tunnel.service
else
	if rc-service edgeguard-agent status >/dev/null 2>&1; then
		rc-service edgeguard-agent restart
	else
		rc-service edgeguard-agent start
	fi
fi

printf '%s\n' \
	'EdgeGuard Agent installed, enrolled and started.' \
	"Requested local Origin: $origin_url" \
	'Configure the public domain and route in the customer portal.'
