#!/bin/sh /etc/rc.common

USE_PROCD=1
START=99
STOP=10

NAME=tailscale-settings

# Compare version strings: return 0 (true) if $1 >= $2
version_gte() {
	awk -v a="${1%%-*}" -v b="${2%%-*}" 'BEGIN {
		split(a, av, ".")
		split(b, bv, ".")
		for (i=1; i<=3; i++) {
			ai = int(av[i]+0); bi = int(bv[i]+0)
			if (ai > bi) { exit 0 }
			if (ai < bi) { exit 1 }
		}
		exit 0
	}'
	return $?
}

apply_settings() {
	local ts_bin
	if [ -x /usr/sbin/tailscale ]; then
		ts_bin=/usr/sbin/tailscale
	elif [ -x /usr/bin/tailscale ]; then
		ts_bin=/usr/bin/tailscale
	else
		logger -t "$NAME" "tailscale binary not found, skipping settings apply"
		return 0
	fi

	config_load tailscale

	local accept_routes advertise_exit_node exit_node exit_node_allow_lan_access
	local ssh disable_magic_dns shields_up runwebclient nosnat hostname
	local enable_relay relay_server_port

	config_get accept_routes              settings accept_routes              '0'
	config_get advertise_exit_node        settings advertise_exit_node        '0'
	config_get exit_node                  settings exit_node                  ''
	config_get exit_node_allow_lan_access settings exit_node_allow_lan_access '0'
	config_get ssh                        settings ssh                        '0'
	config_get disable_magic_dns          settings disable_magic_dns          '0'
	config_get shields_up                 settings shields_up                 '0'
	config_get runwebclient               settings runwebclient               '0'
	config_get nosnat                     settings nosnat                     '0'
	config_get hostname                   settings hostname                   ''
	config_get enable_relay               settings enable_relay               '0'
	config_get relay_server_port          settings relay_server_port          '40000'

	# Collect advertise_routes UCI list into comma-separated string
	local routes=""
	append_route() {
		if [ -z "$routes" ]; then
			routes="$1"
		else
			routes="$routes,$1"
		fi
	}
	config_list_foreach settings advertise_routes append_route

	# Build argument list for 'tailscale set'
	set -- set

	# --accept-routes
	[ "$accept_routes" = "1" ] \
		&& set -- "$@" --accept-routes=true \
		|| set -- "$@" --accept-routes=false

	# --advertise-exit-node (only when no exit node is selected)
	if [ "$advertise_exit_node" = "1" ] && [ -z "$exit_node" ]; then
		set -- "$@" --advertise-exit-node=true
	else
		set -- "$@" --advertise-exit-node=false
	fi

	# --exit-node-allow-lan-access (only when no exit node is selected)
	if [ -z "$exit_node" ]; then
		[ "$exit_node_allow_lan_access" = "1" ] \
			&& set -- "$@" --exit-node-allow-lan-access=true \
			|| set -- "$@" --exit-node-allow-lan-access=false
	fi

	# --ssh
	[ "$ssh" = "1" ] \
		&& set -- "$@" --ssh=true \
		|| set -- "$@" --ssh=false

	# --accept-dns (inverse of disable_magic_dns)
	[ "$disable_magic_dns" = "1" ] \
		&& set -- "$@" --accept-dns=false \
		|| set -- "$@" --accept-dns=true

	# --shields-up
	[ "$shields_up" = "1" ] \
		&& set -- "$@" --shields-up=true \
		|| set -- "$@" --shields-up=false

	# --webclient
	[ "$runwebclient" = "1" ] \
		&& set -- "$@" --webclient=true \
		|| set -- "$@" --webclient=false

	# --snat-subnet-routes (inverse of nosnat)
	[ "$nosnat" = "1" ] \
		&& set -- "$@" --snat-subnet-routes=false \
		|| set -- "$@" --snat-subnet-routes=true

	# --advertise-routes (comma-separated, empty clears routes)
	set -- "$@" "--advertise-routes=$routes"

	# --exit-node (empty clears the exit node)
	set -- "$@" "--exit-node=$exit_node"

	# when an exit node is configured, always allow LAN access
	[ -n "$exit_node" ] && set -- "$@" --exit-node-allow-lan-access=true

	# --hostname (only set if non-empty)
	[ -n "$hostname" ] && set -- "$@" "--hostname=$hostname"

	# --relay-server-port (requires tailscale >= 1.90.5)
	local ts_ver
	ts_ver=$("$ts_bin" version 2>/dev/null | head -n1)
	if version_gte "$ts_ver" "1.90.5"; then
		if [ "$enable_relay" = "1" ]; then
			set -- "$@" "--relay-server-port=${relay_server_port:-40000}"
		else
			set -- "$@" "--relay-server-port="
		fi
	fi

	logger -t "$NAME" "Applying settings"
	"$ts_bin" "$@"
	local ret=$?
	[ $ret -eq 0 ] \
		&& logger -t "$NAME" "Settings applied successfully" \
		|| logger -t "$NAME" "Failed to apply settings (exit code: $ret)"
	return $ret
}

start_service() {
	apply_settings
}

service_triggers() {
	procd_add_reload_trigger "tailscale"
}

reload_service() {
	apply_settings
}
