#!/bin/sh /etc/rc.common
# procd service for the EdNovas router client agent.

USE_PROCD=1
START=95
STOP=10

CFG=ednovas

start_service() {
	config_load "$CFG"

	local enabled agent_path mihomo_path www_dir ui_dir dl_base mihomo_version mini
	config_get_bool enabled main enabled 1
	[ "$enabled" = "1" ] || return 0

	config_get agent_path   main agent_path   /usr/share/ednovas/ednovas-agent
	config_get mihomo_path  main mihomo_path  /usr/share/ednovas/mihomo
	config_get www_dir      main www_dir      /usr/share/ednovas/www
	config_get ui_dir       main ui_dir       /tmp/ednovas/dashboard
	config_get dl_base      main dl_base      ""
	config_get mihomo_version main mihomo_version "v1.19.17"
	config_get_bool mini    main mini 0

	mkdir -p /etc/ednovas

	# Mini edition: binaries and geodata live on tmpfs. Flash usage stays
	# at the package itself; the price is a re-download on every boot (the
	# WAN hotplug retries until the network is up).
	local geo_dir=/etc/ednovas
	if [ "$mini" = "1" ]; then
		mkdir -p /tmp/ednovas
		# Reclaim flash left behind by a previous standard install: the
		# binaries are runtime downloads, not package files, so switching
		# editions never removes them by itself.
		rm -f /usr/share/ednovas/ednovas-agent /usr/share/ednovas/mihomo
		agent_path=/tmp/ednovas/ednovas-agent
		mihomo_path=/tmp/ednovas/mihomo
		geo_dir=/tmp/ednovas
		# The dashboard archive stays off flash too (agent re-downloads it
		# after boot into /tmp/ednovas).
		rm -f /usr/share/ednovas/dashboard.tgz
		# The core resolves geodata from its work dir; point it at tmpfs.
		for f in geoip.metadb geosite.dat; do
			[ -e "/etc/ednovas/$f" ] && [ ! -L "/etc/ednovas/$f" ] && rm -f "/etc/ednovas/$f"
			ln -sf "/tmp/ednovas/$f" "/etc/ednovas/$f"
		done
	fi

	# The dashboard is SERVED from tmpfs on every edition (extracted on
	# demand from a ~2.5MB archive; the unpacked ~8MB bundle never touches
	# the overlay). Older conffiles carry the pre-dashboard default path.
	case "$ui_dir" in
	""|/usr/share/ednovas/dashboard) ui_dir=/tmp/ednovas/dashboard ;;
	esac
	rm -rf /usr/share/ednovas/dashboard

	# Firmware-provided core (SDK mihomo package baked into the image): use
	# it and skip the core download -- zero overlay and zero RAM cost. Only
	# a binary present in /rom qualifies: a feed-installed /usr/bin/mihomo
	# (overlay only, e.g. another luci app's core package) has an arbitrary
	# version and must not silently replace the pinned managed core. A
	# custom mihomo_path is an explicit user choice and always wins.
	local def_core=/usr/share/ednovas/mihomo
	[ "$mini" = "1" ] && def_core=/tmp/ednovas/mihomo
	if [ "$mihomo_path" = "$def_core" ] && [ ! -x "$mihomo_path" ] \
		&& [ -x /rom/usr/bin/mihomo ] && [ -x /usr/bin/mihomo ]; then
		mihomo_path=/usr/bin/mihomo
		logger -t ednovas "using firmware-provided mihomo (/usr/bin/mihomo, from /rom)"
	fi

	# The package is Architecture: all; the agent binary is fetched at
	# runtime. After an ipk upgrade the old binary is still on disk, so a
	# version mismatch against the package must force a re-download or the
	# client keeps running (and reporting) the old version forever.
	local force_agent="" pkg_ver agent_ver
	pkg_ver="$(cat /usr/share/ednovas/VERSION 2>/dev/null | tr -d ' \t\r\n')"
	if [ -x "$agent_path" ] && [ -n "$pkg_ver" ]; then
		agent_ver="$("$agent_path" version 2>/dev/null | tr -d ' \t\r\n')"
		if [ -n "$agent_ver" ] && [ "$agent_ver" != "dev" ] && [ "$agent_ver" != "$pkg_ver" ]; then
			logger -t ednovas "agent $agent_ver != package $pkg_ver; refreshing agent"
			force_agent=1
		fi
	fi

	# Fetch agent + core for this architecture on first start (or refresh the
	# agent after a package upgrade; download is atomic, failure keeps the
	# existing binary).
	if [ ! -x "$agent_path" ] || [ ! -x "$mihomo_path" ] || [ -n "$force_agent" ]; then
		logger -t ednovas "downloading agent/core for $(uname -m)"
		DL_BASE="$dl_base" MIHOMO_VERSION="$mihomo_version" \
		AGENT_PATH="$agent_path" MIHOMO_PATH="$mihomo_path" \
		AGENT_FORCE="$force_agent" GEO_DIR="$geo_dir" \
		sh /usr/share/ednovas/bootstrap.sh 2>&1 | logger -t ednovas
		if [ ! -x "$agent_path" ] || [ ! -x "$mihomo_path" ]; then
			logger -t ednovas "bootstrap failed; not starting"
			return 1
		fi
	fi

	procd_open_instance
	procd_set_param command "$agent_path" run \
		-dir /etc/ednovas \
		-www "$www_dir" \
		-ui "$ui_dir" \
		-mihomo "$mihomo_path"
	# SAFE_PATHS reaches the core through the agent's environment. The current
	# agent never puts the dashboard dir into the core config, but an agent
	# left over from an earlier build (the post-upgrade re-download can fail
	# offline) still writes "external-ui: $ui_dir", which mihomo >= 1.19.6
	# rejects outside its -d dir -- and that broke login/refresh/settings.
	# Whitelisting the dir keeps such a router working until the agent refreshes.
	procd_set_param env EDNOVAS_DIR=/etc/ednovas SAFE_PATHS="$ui_dir"
	procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}"
	procd_set_param stdout 1
	procd_set_param stderr 1
	procd_set_param pidfile /var/run/ednovas.pid
	procd_close_instance
}

service_triggers() {
	procd_add_reload_trigger "$CFG"
}
