#!/bin/sh
# rpcd object exposing srunc to LuCI / ubus.
#
# Methods:
#   status   {"section": "<name>"}  -> {"online":bool, "username":str|null, "ip":str|null}
#   login    {}                     -> {"ok":bool}        # restarts the procd service
#   logout   {}                     -> {"ok":bool}        # stops the procd service
#   restart  {}                     -> {"ok":bool}
#   profiles {}                     -> {"profiles":[{"id","label","host","ac_id"}, ...]}
#
# `status` reads `/var/run/srunc/<section>.toml` (rendered by the init script
# when the daemon is running); falls back to offline if absent. Action methods
# delegate to /etc/init.d/srunc so the full "render UCI -> TOML -> spawn"
# pipeline runs in one place. `profiles` shells out to the binary so the
# registry stays single-sourced in Rust.

. /usr/share/libubox/jshn.sh

PROG=/usr/sbin/srunc
RUNDIR=/var/run/srunc
INIT=/etc/init.d/srunc

reply_offline() {
	json_init
	json_add_boolean online 0
	json_dump
}

reply_ok() {
	json_init
	json_add_boolean ok 1
	json_dump
}

reply_fail() {
	json_init
	json_add_boolean ok 0
	[ -n "$1" ] && json_add_string error "$1"
	json_dump
}

case "$1" in
list)
	json_init
	json_add_object "status";  json_add_string section "";  json_close_object
	json_add_object "login";   json_close_object
	json_add_object "logout";  json_close_object
	json_add_object "restart";  json_close_object
	json_add_object "profiles"; json_close_object
	json_dump
	;;

call)
	# Args arrive as one JSON object on stdin.
	json_load "$(cat)"
	json_get_var section section
	section="${section:-default}"
	cfg="$RUNDIR/$section.toml"

	case "$2" in
	status)
		if [ -f "$cfg" ]; then
			out=$("$PROG" -c "$cfg" status --json 2>/dev/null) || out=""
			if [ -n "$out" ]; then
				printf '%s' "$out"
			else
				reply_offline
			fi
		else
			reply_offline
		fi
		;;
	login)
		if "$INIT" restart >/dev/null 2>&1; then
			reply_ok
		else
			reply_fail "init.d restart failed"
		fi
		;;
	logout)
		# Best-effort portal logout, then stop the keepalive daemon.
		if [ -f "$cfg" ]; then
			"$PROG" -c "$cfg" logout >/dev/null 2>&1 || true
		fi
		if "$INIT" stop >/dev/null 2>&1; then
			reply_ok
		else
			reply_fail "init.d stop failed"
		fi
		;;
	restart)
		if "$INIT" restart >/dev/null 2>&1; then
			reply_ok
		else
			reply_fail "init.d restart failed"
		fi
		;;
	profiles)
		# Defer to the binary so the registry lives in exactly one place.
		# Output is already an array of {id,label,host,ac_id}; wrap it in
		# the {profiles: [...]} envelope LuCI expects from an ubus method.
		out=$("$PROG" profiles list --json 2>/dev/null) || out="[]"
		printf '{"profiles":%s}\n' "$out"
		;;
	*)
		reply_fail "unknown method"
		;;
	esac
	;;
esac
