#!/bin/sh /etc/rc.common
# Copyright (C) 2023 Tianling Shen <cnsztl@immortalwrt.org>
# daed-guard handles bounded child shutdown and post-exit netns/veth cleanup.
# Keep the log file and a pre-stop state snapshot for diagnostics.

USE_PROCD=1
START=99

CONF="daed"
PROG="/usr/bin/daed-guard"
LOG="/var/log/daed/daed.log"

. /usr/share/daed/cleanup.sh

log() {
	logger -t daed-init "$@"
}

start_service() {
	log "start: begin"
	config_load "$CONF"

	local enabled
	config_get_bool enabled "config" "enabled" "0"
	if [ "$enabled" -ne "1" ]; then
		log "start: config disabled, exit"
		return 1
	fi

	local listen_addr log_maxbackups log_maxsize
	config_get listen_addr "config" "listen_addr" "0.0.0.0:2023"
	config_get log_maxbackups "config" "log_maxbackups" "1"
	config_get log_maxsize "config" "log_maxsize" "5"

	log "start: listen=$listen_addr log_maxbackups=$log_maxbackups log_maxsize=$log_maxsize"

	procd_open_instance "$CONF"
	procd_set_param env DAE_LOCATION_ASSET="/usr/share/v2ray" TZ="$(uci -q get system.@system[0].zonename)"
	procd_set_param command "$PROG" run
	procd_append_param command --config "/etc/daed/"
	procd_append_param command --listen "$listen_addr"
	procd_append_param command --logfile "$LOG"
	procd_append_param command --logfile-maxbackups "$log_maxbackups"
	procd_append_param command --logfile-maxsize "$log_maxsize"

	procd_set_param limits core="unlimited"
	procd_set_param limits nofile="1000000 1000000"
	# daed-guard escalates its child after 20 seconds. Leave time for
	# reap and post-exit cleanup before procd kills the wrapper.
	procd_set_param term_timeout 30
	# procd_set_param respawn: arguments are (threshold, timeout, retry).
	#   threshold = runtime that resets the short-lived exit counter
	#   timeout   = seconds to wait between retries
	#   retry     = maximum short-lived exits before procd gives up
	# Reset the counter after one hour of stable runtime; otherwise retry
	# after 5 seconds and stop after 10 failures.
	procd_set_param respawn 3600 5 10
	# daed-guard sets oom_score_adj before forking; procd has no
	# oom_adj/oom_score_adj parameter.
	# procd_set_param stdout 1
	procd_set_param stderr 1

	procd_close_instance
	log "start: procd_open_instance done"
}

stop_service() {
	log "stop: begin"
	# Cleanup runs in daed-guard after its child exits. Record only a
	# pre-stop snapshot here; pin entries do not prove TC attachment.
	local pinned="" ns_left=""
	if [ -d /sys/fs/bpf/daed ]; then
		pinned=$(ls /sys/fs/bpf/daed 2>/dev/null | tr '\n' ' ')
	fi
	if ip netns list 2>/dev/null | grep -q '^daens'; then
		ns_left="daens"
	fi
	log "stop: pre-stop state — bpf_pin_entries=[${pinned:-none}] netns_left=[${ns_left:-none}]"
}

service_triggers() {
	procd_add_reload_trigger "$CONF"
}
