#!/bin/sh

action="$1"
[ "$action" = "start" ] || [ "$action" = "stop" ] || exit 2

request_file="${VOIP_LOCAL_REQUEST_FILE:-/tmp/voip-local-apply.request}"
applied_file="${VOIP_LOCAL_APPLIED_FILE:-/tmp/voip-local-apply.applied}"
lock_dir="${VOIP_LOCAL_LOCK_DIR:-/tmp/voip-local-apply.lock}"
voip_init="${VOIP_LOCAL_INIT:-/etc/init.d/voip}"
log_file="${VOIP_LOCAL_LOG:-/tmp/voip-local.log}"
client_pid_file="${VOIP_LOCAL_CLIENT_PID_FILE:-/var/run/clientsip.pid}"
coalesce_delay="${VOIP_LOCAL_COALESCE_DELAY:-1}"
lock_delay="${VOIP_LOCAL_LOCK_DELAY:-1}"
retry_delay="${VOIP_LOCAL_RETRY_DELAY:-15}"
request_id="$(date +%s).$$"

printf '%s %s\n' "$request_id" "$action" >"$request_file.new.$$" || exit 1
mv "$request_file.new.$$" "$request_file" || exit 1

(
	while ! mkdir "$lock_dir" 2>/dev/null; do sleep "$lock_delay"; done
	trap 'rmdir "$lock_dir" 2>/dev/null' EXIT

	while :; do
		request=$(cat "$request_file" 2>/dev/null) || exit 1
		applied=$(cat "$applied_file" 2>/dev/null)
		[ "$request" != "$applied" ] || exit 0

		# Collapse a burst of WebUI saves before touching the proprietary DSP.
		sleep "$coalesce_delay"
		request=$(cat "$request_file" 2>/dev/null) || exit 1
		current_action=${request#* }
		apply_status=0
		"$voip_init" local_apply_now "$current_action" || apply_status=$?
		if [ "$apply_status" -ne 0 ] && [ "$current_action" = "start" ]; then
			# clientSip deliberately terminates its launcher with SIGUSR2. The
			# launcher status is therefore not authoritative when the daemon
			# recorded in its own pidfile is alive.
			sip_pid=$(cat "$client_pid_file" 2>/dev/null)
			if [ -n "$sip_pid" ] && kill -0 "$sip_pid" 2>/dev/null; then
				apply_status=0
			fi
		fi
		if [ "$apply_status" -ne 0 ]; then
			echo "voip-local-apply: $current_action failed; retrying in $retry_delay seconds"
			sleep "$retry_delay"
			continue
		fi
		printf '%s\n' "$request" >"$applied_file" || exit 1

		# If another save arrived during the slow stop/start sequence, apply its
		# final state in the same worker. Waiting workers will then exit cleanly.
		[ "$request" = "$(cat "$request_file" 2>/dev/null)" ] && exit 0
	done
) >>"$log_file" 2>&1 &

exit 0
