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

START=99

USE_PROCD=1

PROG=/usr/bin/zerotier-one
CONFIG_PATH=/var/lib/zerotier-luci

service_triggers() {
	procd_add_reload_trigger "zerotier"
	procd_add_interface_trigger "interface.*.up" wan /etc/init.d/luci_zerotier restart
}

iptables_w() {
	iptables -w 1 "$@"
}

section_enabled() {
	config_get_bool enabled "$1" 'enabled' 0
	[ $enabled -gt 0 ]
}

start_instance() {
	local cfg="$1"
	local port secret config_path
	local ARGS=""

	if ! section_enabled "$cfg"; then
		echo "disabled in config"
		return 1
	fi

	[ -d /etc/config/zero ] || mkdir -p /etc/config/zero
	config_path=/etc/config/zero

	# Remove existing link or folder
	rm -rf $CONFIG_PATH

	# Create link from CONFIG_PATH to config_path
	if [ -n "$config_path" -a "$config_path" != $CONFIG_PATH ]; then
		if [ ! -d "$config_path" ]; then
			echo "ZeroTier config_path does not exist: $config_path"
			return
		fi

		mkdir -p /var/lib
		ln -s $config_path $CONFIG_PATH
	fi

	mkdir -p $CONFIG_PATH/networks.d

	config_get port $cfg 'port'
	[ -f "$CONFIG_PATH/identity.secret" ] || config_get secret $cfg 'secret' "generate"

	if [ -n "$port" ]; then
		ARGS="$ARGS -p$port"
	fi

	if [ "$secret" = "generate" ]; then
		echo "Generate secret - please wait..."
		local sf="/tmp/zt.$cfg.secret"

		zerotier-idtool generate "$sf" > /dev/null
		[ $? -ne 0 ] && return 1

		secret="$(cat $sf)"
		rm "$sf"

		uci set zerotier.$cfg.secret="$secret"
		uci commit zerotier
	fi

	if [ -n "$secret" ]; then
		echo "$secret" > $CONFIG_PATH/identity.secret
		# make sure there is not previous identity.public
		rm -f $CONFIG_PATH/identity.public
	fi

	zt_local() {
		local network uci zt default
		network=$2
		default=$4
		zt=$5
		config_get uci $1 $3 $default
		[ "$uci" = "$default" ] && return 0
		echo "$zt=$uci" >> $CONFIG_PATH/networks.d/$network.local.conf
	}

	add_join() {
		local enabled network
		config_get_bool enabled $1 enabled 0
		[ "$enabled" = 1 ] || return 0
		config_get network $1 network
		[ -n "$network" ] || return 0
		# an (empty) config file will cause ZT to join a network
		touch $CONFIG_PATH/networks.d/$network.conf
		zt_local $1 "$network" allow_managed 1 allowManaged
		zt_local $1 "$network" allow_global 0 allowGlobal
		zt_local $1 "$network" allow_default 0 allowDefault
		zt_local $1 "$network" allow_dns 0 allowDNS
	}

	rm -f $CONFIG_PATH/networks.d/*.conf
	rm -f $CONFIG_PATH/networks.d/*.local.conf
	config_foreach add_join 'join'

	procd_open_instance
	procd_set_param command $PROG $ARGS $CONFIG_PATH
	procd_set_param file /etc/config/zerotier
	procd_set_param stderr 1
	procd_set_param respawn
	procd_close_instance
}

start_service() {
	/etc/init.d/zerotier stop 2>/dev/null
	local nat
	config_load 'zerotier'
	config_get_bool nat "sample_config" 'nat' 0
	config_get_bool enabled "sample_config" 'enabled' 0
	if [ $enabled -eq 1 ]; then
		mkdir -p /var/run/zerotier
		mkdir -p /tmp/dnsmasq.d/zerotier
		>/tmp/dnsmasq.d/zerotier/dns.conf
		echo "conf-dir=/tmp/dnsmasq.d/zerotier" >/tmp/dnsmasq.d/zerotier.conf
		touch /var/run/zerotier/dns.enabled
		if [ "$nat" -eq 1 ]; then
			touch /var/run/zerotier/nat.enabled
			/usr/libexec/zerotier-nat init
			echo "/usr/libexec/zerotier-nat init" >/var/etc/zerotier.include
		else
			rm -f /var/etc/zerotier.include /var/run/zerotier/nat.enabled
			/usr/libexec/zerotier-nat deinit
		fi
	else
		stop_service
		return 0
	fi

	if [ "$nat" -eq 1 ]; then
		procd_open_instance zerotier_nat
		procd_set_param command /usr/libexec/zerotier-nat
		procd_close_instance
	fi
	procd_open_instance zerotier_dns
	procd_set_param command /usr/libexec/zerotier-dns
	procd_close_instance
	start_instance "sample_config"
}

stop_service() {
	rm -f /var/etc/zerotier.include /var/run/zerotier/dns.enabled /var/run/zerotier/nat.enabled
	if [ -e /tmp/dnsmasq.d/zerotier.conf ];then
		rm -f /tmp/dnsmasq.d/zerotier.conf
		/etc/init.d/dnsmasq enabled && /etc/init.d/dnsmasq restart
	fi
	rm -rf /tmp/dnsmasq.d/zerotier
	rm -rf /var/run/zerotier
	/usr/libexec/zerotier-nat deinit
}
