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

USE_PROCD=1
START=99



enable_captive_portal() {
	local IP=$(uci -q get network.lan.ipaddr || echo "192.168.1.1")
	IP="${IP%%/*}"
	local confdir=$(uci -q get dhcp.@dnsmasq[0].confdir || echo "/tmp/dnsmasq.d")

	mkdir -p "$confdir"
	if [ -f /usr/share/wizard/captive-portal.conf.tpl ]; then
		sed "s/\$PORTAL_IP/$IP/g" /usr/share/wizard/captive-portal.conf.tpl > "$confdir/captive-portal.conf"
	fi
	/etc/init.d/dnsmasq restart

	for handle in $(nft -a list chain inet fw4 dstnat 2>/dev/null | awk '/captive-portal/{print $NF}'); do
		nft delete rule inet fw4 dstnat handle "$handle" 2>/dev/null
	done
	nft add rule inet fw4 dstnat iifname "br-lan" ip daddr != "$IP" tcp dport 80 counter dnat to "$IP":80 comment \"captive-portal\"
	nft add rule inet fw4 dstnat iifname "br-lan" ip daddr != "$IP" udp dport 53 counter dnat to "$IP":53 comment \"captive-portal\"
	nft add rule inet fw4 dstnat iifname "br-lan" ip daddr != "$IP" tcp dport 53 counter dnat to "$IP":53 comment \"captive-portal\"

	uci -q set uhttpd.main.error_page='/cgi-bin/captive-handler'
	uci commit uhttpd
	/etc/init.d/uhttpd restart

	touch /tmp/captive-portal-active
}

disable_captive_portal() {
	rm -f /tmp/captive-portal-active
	for handle in $(nft -a list chain inet fw4 dstnat 2>/dev/null | awk '/captive-portal/{print $NF}'); do
		nft delete rule inet fw4 dstnat handle "$handle" 2>/dev/null
	done

	local confdir=$(uci -q get dhcp.@dnsmasq[0].confdir || echo "/tmp/dnsmasq.d")
	local dns_changed=0
	if [ -f "$confdir/captive-portal.conf" ]; then
		rm -f "$confdir/captive-portal.conf"
		dns_changed=1
	fi

	if [ -n "$(uci -q get uhttpd.main.error_page)" ]; then
		uci -q delete uhttpd.main.error_page
		uci commit uhttpd
		/etc/init.d/uhttpd restart
	fi

	[ "$dns_changed" = "1" ] && /etc/init.d/dnsmasq restart
}

sync_wizard() {
	local changed=0

	# wan
	local WAN_PROTO=$(uci -q get network.wan.proto)
	local CUR_WAN_PROTO=$(uci -q get wizard.default.wan_proto)

	if [ "$WAN_PROTO" != "$CUR_WAN_PROTO" ]; then
		uci -q set wizard.default.wan_proto="$WAN_PROTO"
		changed=1
	fi

	case "$WAN_PROTO" in
	dhcp)
		uci -q del wizard.default.wan_pppoe_user
		uci -q del wizard.default.wan_pppoe_pass
		uci -q del wizard.default.wan_l2tp_server
		uci -q del wizard.default.wan_l2tp_user
		uci -q del wizard.default.wan_l2tp_pass
		uci -q del wizard.default.wan_pptp_server
		uci -q del wizard.default.wan_pptp_user
		uci -q del wizard.default.wan_pptp_pass
		uci -q del wizard.default.wan_ipaddr
		uci -q del wizard.default.wan_netmask
		uci -q del wizard.default.wan_gateway

		local DNS=$(uci -q get network.wan.dns)
		local CUR_DNS=$(uci -q get wizard.default.wan_dns)

		if [ "$DNS" != "$CUR_DNS" ]; then
			uci -q del wizard.default.wan_dns
			for d in $DNS; do
				uci -q add_list wizard.default.wan_dns="$d"
			done
			changed=1
		fi
	;;

	static)
		uci -q del wizard.default.wan_pppoe_user
		uci -q del wizard.default.wan_pppoe_pass
		uci -q del wizard.default.wan_l2tp_server
		uci -q del wizard.default.wan_l2tp_user
		uci -q del wizard.default.wan_l2tp_pass
		uci -q del wizard.default.wan_pptp_server
		uci -q del wizard.default.wan_pptp_user
		uci -q del wizard.default.wan_pptp_pass

		local IP=$(uci -q get network.wan.ipaddr)
		local NM=$(uci -q get network.wan.netmask)
		local GW=$(uci -q get network.wan.gateway)
		local DNS=$(uci -q get network.wan.dns)
		local CUR_DNS=$(uci -q get wizard.default.wan_dns)

		[ "$IP" != "$(uci -q get wizard.default.wan_ipaddr)" ] && {
			uci -q set wizard.default.wan_ipaddr="$IP"
			changed=1
		}

		[ "$NM" != "$(uci -q get wizard.default.wan_netmask)" ] && {
			uci -q set wizard.default.wan_netmask="$NM"
			changed=1
		}

		[ "$GW" != "$(uci -q get wizard.default.wan_gateway)" ] && {
			uci -q set wizard.default.wan_gateway="$GW"
			changed=1
		}

		if [ "$DNS" != "$CUR_DNS" ]; then
			uci -q del wizard.default.wan_dns
			for d in $DNS; do
				uci -q add_list wizard.default.wan_dns="$d"
			done
			changed=1
		fi
	;;

	pppoe)
		uci -q del wizard.default.wan_ipaddr
		uci -q del wizard.default.wan_netmask
		uci -q del wizard.default.wan_gateway
		uci -q del wizard.default.wan_l2tp_server
		uci -q del wizard.default.wan_l2tp_user
		uci -q del wizard.default.wan_l2tp_pass
		uci -q del wizard.default.wan_pptp_server
		uci -q del wizard.default.wan_pptp_user
		uci -q del wizard.default.wan_pptp_pass

		local USER=$(uci -q get network.wan.username)
		local PASS=$(uci -q get network.wan.password)
		local DNS=$(uci -q get network.wan.dns)
		local CUR_DNS=$(uci -q get wizard.default.wan_dns)

		[ "$USER" != "$(uci -q get wizard.default.wan_pppoe_user)" ] && {
			uci -q set wizard.default.wan_pppoe_user="$USER"
			changed=1
		}

		[ "$PASS" != "$(uci -q get wizard.default.wan_pppoe_pass)" ] && {
			uci -q set wizard.default.wan_pppoe_pass="$PASS"
			changed=1
		}

		if [ "$DNS" != "$CUR_DNS" ]; then
			uci -q del wizard.default.wan_dns
			for d in $DNS; do
				uci -q add_list wizard.default.wan_dns="$d"
			done
			changed=1
		fi
	;;

	l2tp)
		uci -q del wizard.default.wan_ipaddr
		uci -q del wizard.default.wan_netmask
		uci -q del wizard.default.wan_gateway
		uci -q del wizard.default.wan_pppoe_user
		uci -q del wizard.default.wan_pppoe_pass
		uci -q del wizard.default.wan_pptp_server
		uci -q del wizard.default.wan_pptp_user
		uci -q del wizard.default.wan_pptp_pass

		local SERVER=$(uci -q get network.l2tp.server)
		local USER=$(uci -q get network.l2tp.username)
		local PASS=$(uci -q get network.l2tp.password)
		local DNS=$(uci -q get network.l2tp.dns)
		local CUR_DNS=$(uci -q get wizard.default.wan_dns)

		[ "$SERVER" != "$(uci -q get wizard.default.wan_l2tp_server)" ] && {
			uci -q set wizard.default.wan_l2tp_server="$SERVER"
			changed=1
		}

		[ "$USER" != "$(uci -q get wizard.default.wan_l2tp_user)" ] && {
			uci -q set wizard.default.wan_l2tp_user="$USER"
			changed=1
		}

		[ "$PASS" != "$(uci -q get wizard.default.wan_l2tp_pass)" ] && {
			uci -q set wizard.default.wan_l2tp_pass="$PASS"
			changed=1
		}

		if [ "$DNS" != "$CUR_DNS" ]; then
			uci -q del wizard.default.wan_dns
			for d in $DNS; do
				uci -q add_list wizard.default.wan_dns="$d"
			done
			changed=1
		fi
	;;

	pptp)
		uci -q del wizard.default.wan_ipaddr
		uci -q del wizard.default.wan_netmask
		uci -q del wizard.default.wan_gateway
		uci -q del wizard.default.wan_pppoe_user
		uci -q del wizard.default.wan_pppoe_pass
		uci -q del wizard.default.wan_l2tp_server
		uci -q del wizard.default.wan_l2tp_user
		uci -q del wizard.default.wan_l2tp_pass

		local SERVER=$(uci -q get network.pptp.server)
		local USER=$(uci -q get network.pptp.username)
		local PASS=$(uci -q get network.pptp.password)
		local DNS=$(uci -q get network.pptp.dns)
		local CUR_DNS=$(uci -q get wizard.default.wan_dns)

		[ "$SERVER" != "$(uci -q get wizard.default.wan_pptp_server)" ] && {
			uci -q set wizard.default.wan_pptp_server="$SERVER"
			changed=1
		}

		[ "$USER" != "$(uci -q get wizard.default.wan_pptp_user)" ] && {
			uci -q set wizard.default.wan_pptp_user="$USER"
			changed=1
		}

		[ "$PASS" != "$(uci -q get wizard.default.wan_pptp_pass)" ] && {
			uci -q set wizard.default.wan_pptp_pass="$PASS"
			changed=1
		}

		if [ "$DNS" != "$CUR_DNS" ]; then
			uci -q del wizard.default.wan_dns
			for d in $DNS; do
				uci -q add_list wizard.default.wan_dns="$d"
			done
			changed=1
		fi
	;;

	esac

	# lan
	local IPADDR=$(uci -q get network.lan.ipaddr)
	local NETMASK=$(uci -q get network.lan.netmask)

	[ "$IPADDR" != "$(uci -q get wizard.default.lan_ipaddr)" ] && {
		uci -q set wizard.default.lan_ipaddr="$IPADDR"
		changed=1
	}

	[ "$NETMASK" != "$(uci -q get wizard.default.lan_netmask)" ] && {
		uci -q set wizard.default.lan_netmask="$NETMASK"
		changed=1
	}

	# mac

	local device=$(uci -q get wizard.default.hw_wan)
	local wandevsec=$(uci show network | grep "name='$device'" | sed -n "s/^network\.\(@device\[[0-9]\+\]\)\.name=.*/\1/p")
	local mac=$(uci -q get network.$wandevsec.macaddr)
	[ -z "$mac" ] && mac=$(cat /sys/class/net/$device/address)
	

	[ "$mac" != "$(uci -q get wizard.default.wan_mac)" ] && {
		uci -q set wizard.default.wan_mac="$mac"
		changed=1
	}

	# wifi
	local SSID2=$(uci -q get wireless.@wifi-iface[0].ssid)
	local KEY2=$(uci -q get wireless.@wifi-iface[0].key)
	local SSID5=$(uci -q get wireless.@wifi-iface[1].ssid)
	local KEY5=$(uci -q get wireless.@wifi-iface[1].key)

	local unify=0
	[ "$SSID2" = "$SSID5" ] && unify=1

	local CUR_UNIFY=$(uci -q get wizard.default.unify_ssid)

	if [ "$unify" = "1" ]; then
		[ "$CUR_UNIFY" != "1" ] && {
			uci -q set wizard.default.unify_ssid="1"
			uci -q del wizard.default.wifi_ssid2
			uci -q del wizard.default.wifi_key2
			uci -q del wizard.default.wifi_ssid5
			uci -q del wizard.default.wifi_key5
			changed=1
		}

		[ "$SSID2" != "$(uci -q get wizard.default.wifi_ssid)" ] && {
			uci -q set wizard.default.wifi_ssid="$SSID2"
			changed=1
		}

		[ "$KEY2" != "$(uci -q get wizard.default.wifi_key)" ] && {
			uci -q set wizard.default.wifi_key="$KEY2"
			changed=1
		}
	else
		[ "$CUR_UNIFY" != "0" ] && {
			uci -q set wizard.default.unify_ssid="0"
			uci -q del wizard.default.wifi_ssid
			uci -q del wizard.default.wifi_key
			changed=1
		}

		[ "$SSID2" != "$(uci -q get wizard.default.wifi_ssid2)" ] && {
			uci -q set wizard.default.wifi_ssid2="$SSID2"
			changed=1
		}

		[ "$KEY2" != "$(uci -q get wizard.default.wifi_key2)" ] && {
			uci -q set wizard.default.wifi_key2="$KEY2"
			changed=1
		}

		[ "$SSID5" != "$(uci -q get wizard.default.wifi_ssid5)" ] && {
			uci -q set wizard.default.wifi_ssid5="$SSID5"
			changed=1
		}

		[ "$KEY5" != "$(uci -q get wizard.default.wifi_key5)" ] && {
			uci -q set wizard.default.wifi_key5="$KEY5"
			changed=1
		}
	fi

	for radio in $(uci show wireless | awk -F'[.=]' '/=wifi-device/ {print $2}'); do
		local band=$(uci -q get wireless.$radio.band)
		local channel=$(uci -q get wireless.$radio.channel)
		local curch=$(uci -q get wizard.default.channel_radio${band})

		if [ "$channel" != "$curch" ]; then
			uci -q set wizard.default.channel_radio${band}="$channel"
			changed=1
		fi
	done

	[ "$changed" = "1" ] && uci commit wizard
}

set_wizard() {
	if [ -n "$WIZARD_BOOT" ]; then
		return 0
	fi

	local wizard_cfg="/etc/config/wizard"
	if [ -f "$wizard_cfg" ]; then
		if find "$wizard_cfg" -mmin +0 | grep -q .; then
			return 0
		fi
	fi

	local cfg="$1"
	local wan_proto hw_mac hw_wan wan_mac wan_ipaddr wan_netmask wan_gateway wan_dns wan_pppoe_user wan_pppoe_pass wan_l2tp_server wan_l2tp_user wan_l2tp_pass wan_pptp_server wan_pptp_user wan_pptp_pass ipv6
	local wifi_ssid wifi_key wifi_ssid2 wifi_key2 wifi_ssid5 wifi_key5
	local mesh_enabled mesh_mode mesh_band mesh_id mesh_key
	local unify_ssid
	local lan_ipaddr lan_netmask

	config_get hw_wan "$cfg" hw_wan
	local wandevsec=$(uci show network | grep ${hw_wan} | grep name | sed -n "s/^network\.\(@device\[[0-9]\+\]\)\.name=.*/\1/p")
	local mac=$(uci -q get network.$wandevsec.macaddr)
	[ -z "$mac" ] && mac=$(cat /sys/class/net/${hw_wan}/address 2>/dev/null)

	config_get unify_ssid "$cfg" unify_ssid
	config_get wifi_key "$cfg" wifi_key
	config_get wifi_key2 "$cfg" wifi_key2
	config_get wifi_key5 "$cfg" wifi_key5

	if [ "$unify_ssid" = "1" ]; then
		[ -z "$wifi_key" ] && return 0
	else
		{ [ -z "$wifi_key2" ] || [ -z "$wifi_key5" ]; } && return 0
	fi

	config_get ipv6 "$cfg" ipv6 '0'

	initial_state=$(sysctl -n net.ipv6.conf.all.disable_ipv6 2>/dev/null)
	local wan6_exists=$(uci -q get network.wan6)
	if [ "$ipv6" = '1' ]; then
		if [ -z "$wan6_exists" ]; then
			/etc/init.d/disable_ipv6 stop
			/etc/init.d/disable_ipv6 disable
			sysctl -qw net.ipv6.conf.all.disable_ipv6=0
			sysctl -qw net.ipv6.conf.default.disable_ipv6=0
			uci -q del dhcp.@dnsmasq[0].filter_aaaa
			uci -q set dhcp.lan.dhcpv6='server'
			uci -q set dhcp.lan.ra='server'
			if ! uci -q get dhcp.lan.ra_flags | grep -qw "managed-config"; then
				uci add_list dhcp.lan.ra_flags='managed-config'
			fi
			if ! uci -q get dhcp.lan.ra_flags | grep -qw "other-config"; then
				uci add_list dhcp.lan.ra_flags='other-config'
			fi
			uci -q set network.wan6=interface
			uci -q set network.wan6.device="${hw_wan}"
			uci -q set network.wan6.proto='dhcpv6'
			uci -q set network.lan.ip6assign='60'
		fi
	else
		/etc/init.d/disable_ipv6 enable
		/etc/init.d/disable_ipv6 start
		uci -q set dhcp.@dnsmasq[0].filter_aaaa='1'
		uci -q del dhcp.lan.dhcpv6
		uci -q del dhcp.lan.ra_flags
		uci -q del dhcp.lan.ra
		uci -q del network.wan6
		uci -q del network.lan.ip6assign
	fi
	final_state=$(sysctl -n net.ipv6.conf.all.disable_ipv6)

	if [ "$initial_state" != "$final_state" ]; then
		sleep 2
		/etc/init.d/network restart
	fi

	config_get wan_proto "$cfg" wan_proto dhcp

	case "${wan_proto}" in
		dhcp)
			config_get hw_mac "$cfg" hw_mac
			config_get wan_mac "$cfg" wan_mac
			uci -q del network.wan
			uci -q del network.l2tp
			uci -q del network.pptp
			uci -q set network.wan=interface
			uci -q set network.wan.device="${hw_wan}"
			uci -q set network.wan.proto='dhcp'
			uci -q set network.$wandevsec.macaddr="${wan_mac:-$hw_mac}"
			config_get wan_dns "$cfg" wan_dns
			test -n "${wan_dns}" && {
				uci -q set network.wan.peerdns='0'
				uci -q set network.wan.dns="${wan_dns}"
			}
		;;
		static)
			config_get hw_mac "$cfg" hw_mac
			config_get wan_mac "$cfg" wan_mac
			config_get wan_ipaddr "$cfg" wan_ipaddr
			config_get wan_netmask "$cfg" wan_netmask
			config_get wan_gateway "$cfg" wan_gateway
			test -n "${wan_ipaddr}" && test -n "${wan_netmask}" && {
				uci -q del network.wan
				uci -q del network.l2tp
				uci -q del network.pptp
				uci -q set network.wan=interface
				uci -q set network.wan.proto='static'
				uci -q set network.wan.device="${hw_wan}"
				uci -q set network.wan.ipaddr="${wan_ipaddr}"
				uci -q set network.wan.netmask="${wan_netmask}"
				uci -q set network.wan.gateway="${wan_gateway}"
				uci -q set network.$wandevsec.macaddr="${wan_mac:-$hw_mac}"

				config_get wan_dns "$cfg" wan_dns
				test -n "${wan_dns}" && {
					uci -q set network.wan.peerdns='0'
					uci -q set network.wan.dns="${wan_dns}"
				}
			}
		;;
		pppoe)
			config_get wan_pppoe_user "$cfg" wan_pppoe_user
			config_get wan_pppoe_pass "$cfg" wan_pppoe_pass
			config_get ipv6 "$cfg" ipv6 '0'
			uci -q del network.wan
			uci -q del network.l2tp
			uci -q del network.pptp
			uci -q set network.wan=interface
			uci -q set network.wan.proto='pppoe'
			uci -q set network.wan.device="${hw_wan}"
			uci -q set network.wan.username="${wan_pppoe_user}"
			uci -q set network.wan.password="${wan_pppoe_pass}"
			uci -q set network.wan.pppd_options='debug'
			uci -q set wizard.default.wan_mac="$mac"
			uci -q set network.wan.ipv6=$( [ "$ipv6" = '1' ] && echo 'auto' || echo '0' )
			config_get wan_dns "$cfg" wan_dns
			test -n "${wan_dns}" && {
				uci -q set network.wan.peerdns='0'
				uci -q set network.wan.dns="${wan_dns}"
			}
		;;
		l2tp)
			config_get wan_l2tp_server "$cfg" wan_l2tp_server
			config_get wan_l2tp_user "$cfg" wan_l2tp_user
			config_get wan_l2tp_pass "$cfg" wan_l2tp_pass
			config_get ipv6 "$cfg" ipv6 '0'
			if [ "$(uci -q get network.wan.proto)" = "pppoe" ]; then
				config_get hw_mac "$cfg" hw_mac
				config_get wan_mac "$cfg" wan_mac
				uci -q del network.wan
				uci -q set network.wan=interface
				uci -q set network.wan.device="${hw_wan}"
				uci -q set network.wan.proto='dhcp'
				uci -q set network.$wandevsec.macaddr="${mac:-$hw_mac}"
			fi
			uci -q del network.wan.dns
			uci -q del network.wan.peerdns
			uci -q del network.l2tp
			uci -q del network.pptp
			uci -q set network.l2tp=interface
			uci -q set network.l2tp.proto='l2tp'
			uci -q set network.l2tp.server="${wan_l2tp_server}"
			uci -q set network.l2tp.username="${wan_l2tp_user}"
			uci -q set network.l2tp.password="${wan_l2tp_pass}"
			uci -q set network.l2tp.mtu='1460'
			uci -q set wizard.default.wan_mac="$mac"
			uci -q set network.l2tp.ipv6=$( [ "$ipv6" = '1' ] && echo 'auto' || echo '0' )
			uci -q set network.wan.metric='1'

			config_get wan_dns "$cfg" wan_dns
			test -n "${wan_dns}" && {
				uci -q set network.l2tp.peerdns='0'
				uci -q set network.l2tp.dns="${wan_dns}"
			}
		;;
		pptp)
			config_get wan_pptp_server "$cfg" wan_pptp_server
			config_get wan_pptp_user "$cfg" wan_pptp_user
			config_get wan_pptp_pass "$cfg" wan_pptp_pass
			config_get ipv6 "$cfg" ipv6 '0'
			if [ "$(uci -q get network.wan.proto)" = "pppoe" ]; then
				config_get hw_mac "$cfg" hw_mac
				config_get wan_mac "$cfg" wan_mac
				uci -q del network.wan
				uci -q set network.wan=interface
				uci -q set network.wan.device="${hw_wan}"
				uci -q set network.wan.proto='dhcp'
				uci -q set network.$wandevsec.macaddr="${mac:-$hw_mac}"
			fi
			uci -q del network.wan.dns
			uci -q del network.wan.peerdns
			uci -q del network.l2tp
			uci -q del network.pptp
			uci -q set network.pptp=interface
			uci -q set network.pptp.proto='pptp'
			uci -q set network.pptp.server="${wan_pptp_server}"
			uci -q set network.pptp.username="${wan_pptp_user}"
			uci -q set network.pptp.password="${wan_pptp_pass}"
			uci -q set network.pptp.mtu='1460'
			uci -q set wizard.default.wan_mac="$mac"
			uci -q set network.pptp.ipv6=$( [ "$ipv6" = '1' ] && echo 'auto' || echo '0' )
			uci -q set network.wan.metric='1'

			config_get wan_dns "$cfg" wan_dns
			test -n "${wan_dns}" && {
				uci -q set network.pptp.peerdns='0'
				uci -q set network.pptp.dns="${wan_dns}"
			}
		;;
	esac

	# Lan Part
	config_get lan_ipaddr "$cfg" lan_ipaddr
	config_get lan_netmask "$cfg" lan_netmask
	config_get mesh_mode "$cfg" mesh_mode
	if [ "$mesh_mode" != "point" ]; then
		test -n "${lan_ipaddr}" && {
			uci -q del dhcp.lan.ignore
			uci -q set network.lan.proto='static'
			uci -q set network.lan.ipaddr="${lan_ipaddr}"
			if [ -n "$lan_netmask" ]; then
				uci -q set network.lan.netmask="$lan_netmask"
			elif echo "$lan_ipaddr" | grep -q '/'; then
				uci -q del network.lan.netmask
			else
				uci -q set network.lan.netmask="255.255.255.0"
			fi
		}
	fi

	# Wi-Fi Part
	config_get wifi_ssid "$cfg" wifi_ssid
	config_get wifi_ssid2 "$cfg" wifi_ssid2
	config_get wifi_ssid5 "$cfg" wifi_ssid5
	config_get mesh_enabled "$cfg" mesh_enabled

	if [ -n "$wifi_ssid" ] || [ -n "$wifi_ssid2" ] || [ -n "$wifi_ssid5" ]; then
		for idx in `seq 0 64`; do
			uci -q get wireless.@wifi-iface[$idx] || break
			[ "$(uci -q get wireless.@wifi-iface[$idx].mode)" = "ap" ] && {
				local radio="$(uci -q get wireless.@wifi-iface[$idx].device)"
				local band="$(uci -q get wireless.${radio}.band | sed s/g//)"
				uci -q del wireless.${radio}.disabled
				if [ -z "$(uci -q get wireless.${radio}.country)" ]; then
					uci -q set wireless.${radio}.country='RU'
				fi
				uci -q set wireless.${radio}.cell_density='0'
				if [ "$unify_ssid" = "1" ]; then
					uci -q set wireless.@wifi-iface[$idx].ssid="${wifi_ssid}"
					uci -q set wireless.@wifi-iface[$idx].key="${wifi_key}"
					if [ -z "$(uci -q get wireless.@wifi-iface[$idx].encryption)" ] || [ "$(uci -q get wireless.@wifi-iface[$idx].encryption)" = "none" ]; then
						uci -q set wireless.@wifi-iface[$idx].encryption='psk2'
					fi
					uci -q set wireless.@wifi-iface[$idx].wps_pushbutton='1'
					uci -q set wireless.@wifi-iface[$idx].ieee80211r='1'
					uci -q set wireless.@wifi-iface[$idx].ieee80211k='1'
					uci -q set wireless.@wifi-iface[$idx].ft_over_ds='0'
					uci -q set wireless.@wifi-iface[$idx].ft_psk_generate_local='1'
					uci -q set wireless.@wifi-iface[$idx].pmk_r1_push='1'
					uci -q set wireless.@wifi-iface[$idx].bss_transition='1'
					uci -q set wireless.@wifi-iface[$idx].proxy_arp='1'
				else
					bandssid="wifi_ssid${band}"
					eval "ssid_value=\"\${$bandssid}\""
					uci -q set wireless.@wifi-iface[$idx].ssid="${ssid_value}"
					bandkey="wifi_key${band}"
					eval "key_value=\"\${$bandkey}\""
					uci -q set wireless.@wifi-iface[$idx].key="${key_value}"
					if [ -z "$(uci -q get wireless.@wifi-iface[$idx].encryption)" ] || [ "$(uci -q get wireless.@wifi-iface[$idx].encryption)" = "none" ]; then
						uci -q set wireless.@wifi-iface[$idx].encryption='psk2'
					fi
					uci -q set wireless.@wifi-iface[$idx].wps_pushbutton='1'
					uci -q del wireless.@wifi-iface[$idx].ieee80211r
					uci -q del wireless.@wifi-iface[$idx].ieee80211k
					uci -q del wireless.@wifi-iface[$idx].ft_over_ds
					uci -q del wireless.@wifi-iface[$idx].ft_psk_generate_local
					uci -q del wireless.@wifi-iface[$idx].pmk_r1_push
					uci -q del wireless.@wifi-iface[$idx].bss_transition
					if [ "$mesh_enabled" = "1" ]; then
						uci -q set wireless.@wifi-iface[$idx].proxy_arp='1'
					else
						uci -q del wireless.@wifi-iface[$idx].proxy_arp
					fi
				fi
			}
		done
	fi

	# Mesh Part
	config_get mesh_enabled "$cfg" mesh_enabled
	config_get mesh_mode "$cfg" mesh_mode
	config_get mesh_band "$cfg" mesh_band
	config_get mesh_id "$cfg" mesh_id
	config_get mesh_key "$cfg" mesh_key
	config_get hw_mac "$cfg" hw_mac
	config_get channel_radio2g "$cfg" channel_radio2g
	config_get channel_radio5g "$cfg" channel_radio5g

	if [ "$mesh_enabled" = "1" ]; then
		for radio in $(uci show wireless | awk -F'[.=]' '/=wifi-device/ {print $2}'); do
			local band
			band="$(uci -q get wireless."$radio".band)"
			if [ "$band" = "2g" ]; then
				uci -q set wireless.${radio}.channel="$channel_radio2g"
			elif [ "$band" = "5g" ]; then
				uci -q set wireless.${radio}.channel="$channel_radio5g"
			fi
		done

		if [ "$mesh_mode" = "point" ]; then
			local current_hostname=$(uci -q get system.@system[0].hostname)
			local hw_mac_clean=${hw_mac//:/}
			if [ "$current_hostname" = "RouteRich" ]; then
				uci -q set system.@system[0].hostname="RR$hw_mac_clean"
				uci commit system
				/etc/init.d/system restart
			fi
			uci -q set dhcp.lan.ignore='1'
			uci -q set network.lan.proto='dhcp'
			uci -q del network.lan.ipaddr
			uci -q del network.lan.netmask
			uci -q del network.lan.ip6assign
			uci -q del network.wan
			uci -q del network.wan6
			uci -q set internet-detector.internet.mod_led_control_enabled='1'
			uci commit internet-detector
			service internet-detector restart
			local lan_device=$(uci show network | grep device | grep name | grep br-lan | awk -F'.' '{print $2}')
			if ! uci -q get network.$lan_device.ports | grep -qw "${hw_wan}"; then
				uci add_list network.$lan_device.ports="${hw_wan}"
				uci -q set network.$lan_device.macaddr="${hw_mac}"
			fi
		else
			local lan_device=$(uci show network | grep device | grep name | grep br-lan | awk -F'.' '{print $2}')
			uci -q del_list network.$lan_device.ports="${hw_wan}"
			uci -q del network.$lan_device.macaddr
			local current_hostname=$(uci -q get system.@system[0].hostname)
			local hw_mac_clean=${hw_mac//:/}
			local lan_mac=$(cat /sys/class/net/br-lan/address)
			uci -q set wizard.default.mesh_controladdr="$lan_mac"
			if [ "$current_hostname" = "RR$hw_mac_clean" ]; then
				uci -q set system.@system[0].hostname="RouteRich"
				uci commit system
				/etc/init.d/system restart
				uci -q set internet-detector.internet.mod_led_control_enabled='0'
				uci commit internet-detector
				service internet-detector restart
				uci -q del wizard.default.wifi_enc_key
				uci -q del wizard.default.wifi_enc_key2
				uci -q del wizard.default.wifi_enc_key5
				uci -q del wizard.default.country_radio2g
				uci -q del wizard.default.country_radio5g
				for idx in `seq 0 64`; do
					uci -q get wireless.@wifi-iface[$idx] || break
					[ "$(uci -q get wireless.@wifi-iface[$idx].mode)" = "ap" ] && {
						local radio="$(uci -q get wireless.@wifi-iface[$idx].device)"
						local band="$(uci -q get wireless.${radio}.band | sed s/g//)"
						uci -q del wireless.${radio}.disabled
						uci -q set wireless.${radio}.country='RU'
						uci -q set wireless.${radio}.cell_density='0'
						if [ "$band" = "2" ]; then
							uci -q set wireless.${radio}.channel='6'
						elif [ "$band" = "5" ]; then
							uci -q set wireless.${radio}.channel='36'
						fi
						uci -q set wireless.@wifi-iface[$idx].ssid="RouteRich_${band}"
						uci -q del wireless.@wifi-iface[$idx].encryption
						uci -q del wireless.@wifi-iface[$idx].key
						uci -q del wireless.@wifi-iface[$idx].wps_pushbutton
					}
				done
			fi
		fi

		case "$mesh_band" in
			2|5)
				local lan_device=$(uci show network | grep device | grep name | grep br-lan | awk -F'.' '{print $2}')
				uci -q del network.$lan_device.stp
				uci -q del wireless.meshnet2
				uci -q del wireless.meshnet5
				mesh_radio=$(uci show wireless | grep ${mesh_band}g | awk -F'.' '{print $2}')
				uci -q set wireless.meshnet=wifi-iface
				uci -q set wireless.meshnet.device="${mesh_radio}"
				uci -q set wireless.meshnet.mode='mesh'
				uci -q set wireless.meshnet.network='lan'
				uci -q set wireless.meshnet.mesh_id="${mesh_id}"
				uci -q set wireless.meshnet.encryption='sae'
				uci -q set wireless.meshnet.key="${mesh_key}"
				uci -q set wireless.meshnet.mesh_rssi_threshold='0'
				uci -q set wireless.meshnet.mesh_fwding='1'
				uci -q set wireless.meshnet.bss_transition='1'
				uci -q set wireless.meshnet.proxy_arp='1'
				uci -q reorder system.led_mesh${mesh_band}='99'
				uci commit system && /etc/init.d/led restart
				;;
			auto)
				local lan_device=$(uci show network | grep device | grep name | grep br-lan | awk -F'.' '{print $2}')
				uci -q set network.$lan_device.stp='1'
				uci -q del wireless.meshnet
				for idx in $(seq 0 64); do
					uci -q get wireless.@wifi-iface[$idx].device || break
					local radio=$(uci -q get wireless.@wifi-iface[$idx].device)
					local band="$(uci -q get wireless.${radio}.band | sed s/g//)"
					uci -q set wireless.meshnet${band}=wifi-iface
					uci -q set wireless.meshnet${band}.device="${radio}"
					uci -q set wireless.meshnet${band}.mode='mesh'
					uci -q set wireless.meshnet${band}.network='lan'
					uci -q set wireless.meshnet${band}.mesh_id="${mesh_id}"
					uci -q set wireless.meshnet${band}.encryption='sae'
					uci -q set wireless.meshnet${band}.key="${mesh_key}"
					uci -q set wireless.meshnet${band}.mesh_rssi_threshold='0'
					uci -q set wireless.meshnet${band}.mesh_fwding='1'
					uci -q set wireless.meshnet${band}.bss_transition='1'
					uci -q set wireless.meshnet${band}.proxy_arp='1'
					uci -q reorder system.led_mesh${band}='99'
				done
				uci commit system && /etc/init.d/led restart
				;;
		esac
	else
		uci -q del wireless.meshnet
		uci -q del wireless.meshnet2
		uci -q del wireless.meshnet5
		local lan_device=$(uci show network | grep device | grep name | grep br-lan | awk -F'.' '{print $2}')
		uci -q del_list network.$lan_device.ports="${hw_wan}"
		uci -q del network.$lan_device.macaddr
		uci -q del network.$lan_device.stp
		local current_hostname=$(uci -q get system.@system[0].hostname)
		local hw_mac_clean=${hw_mac//:/}
		if [ "$current_hostname" = "RR$hw_mac_clean" ]; then
			uci -q set system.@system[0].hostname="RouteRich"
			uci commit system
			/etc/init.d/system restart
			uci -q set internet-detector.internet.mod_led_control_enabled='0'
			uci commit internet-detector
			service internet-detector restart
			uci -q del wizard.default.wifi_enc_key
			uci -q del wizard.default.wifi_enc_key2
			uci -q del wizard.default.wifi_enc_key5
			uci -q del wizard.default.country_radio2g
			uci -q del wizard.default.country_radio5g
			uci -q del wizard.default.mesh_controladdr
			for idx in `seq 0 64`; do
				uci -q get wireless.@wifi-iface[$idx] || break
				[ "$(uci -q get wireless.@wifi-iface[$idx].mode)" = "ap" ] && {
					local radio="$(uci -q get wireless.@wifi-iface[$idx].device)"
					local band="$(uci -q get wireless.${radio}.band | sed s/g//)"
					uci -q del wireless.${radio}.disabled
					uci -q set wireless.${radio}.country='RU'
					uci -q set wireless.${radio}.cell_density='0'
					if [ "$band" = "2" ]; then
						uci -q set wireless.${radio}.channel='6'
					elif [ "$band" = "5" ]; then
						uci -q set wireless.${radio}.channel='36'
					fi
					uci -q set wireless.@wifi-iface[$idx].ssid="RouteRich_${band}"
					uci -q del wireless.@wifi-iface[$idx].encryption
					uci -q del wireless.@wifi-iface[$idx].key
					uci -q del wireless.@wifi-iface[$idx].wps_pushbutton
				}
			done
		fi
	fi

	uci commit wizard
	uci commit dhcp
	uci commit network
	uci commit wireless
	/usr/bin/isptdns
	(
		sleep 15
		/etc/init.d/network reload
		/etc/init.d/dnsmasq reload
		/etc/init.d/mqtt restart
	) &
}

boot() {
	WIZARD_BOOT=1
	sync_wizard
	start "$@"

	# Any node that carries a mesh role has been provisioned -- by the button,
	# by ubus, or by the app -- and must not be held in the setup portal. Only
	# `point` was exempt here, so a Controller kept the captive-portal DNS
	# wildcard (address=/#/<lan ip>) forever unless someone also happened to
	# finish the web wizard or set a root password. The consequences are not
	# cosmetic: every name resolves to the router, so NTP resolves its own pool
	# to the router, the clock never syncs, and on a fresh flash it stays weeks
	# off -- which in turn makes the mesh reject its own signed control-plane
	# commands while the mesh itself looks perfectly healthy.
	local mesh_mode=$(uci -q get wizard.default.mesh_mode)
	case "$mesh_mode" in
	point|controller)
		return 0
		;;
	esac
	local wizard_complete=$(uci -q get wizard.default.wizard_complete)
	local pass=$(awk -F: '/^root:/ {print $2}' /etc/shadow 2>/dev/null)
	if [ "$wizard_complete" != "1" ] && [ -z "$pass" ]; then
		enable_captive_portal
	fi
}

start_service() {
	config_load wizard
	config_foreach set_wizard wizard

	# See boot(): a mesh role of either kind means provisioned. The reload
	# trigger on the `wizard` config makes this fire as soon as pairing writes
	# mesh_mode, so the portal drops immediately rather than at the next boot.
	local mesh_mode=$(uci -q get wizard.default.mesh_mode)
	case "$mesh_mode" in
	point|controller)
		disable_captive_portal
		return 0
		;;
	esac
	local wizard_complete=$(uci -q get wizard.default.wizard_complete)
	local pass=$(awk -F: '/^root:/ {print $2}' /etc/shadow 2>/dev/null)
	if [ "$wizard_complete" = "1" ] || [ -n "$pass" ]; then
		disable_captive_portal
	else
		enable_captive_portal
	fi
}

service_triggers() {
	procd_add_reload_trigger "wizard"
}
