#!/bin/sh

. /lib/functions.sh
. /usr/share/libubox/jshn.sh
. /lib/netmode/netmode_helpers.sh

source "/etc/device_info"

INET_IFACE="wan"
INET_IFACE6="wan6"

IPTV_IFACE="iptv_iface"
IPTV_IFACE6="iptv_iface6"

MGMT_IFACE="mgmt_iface"
MGMT_IFACE6="mgmt_iface6"

IPTV_DEV=""

create_vlan_dev() {
	local ifname="$1"
	local vlanid="$2"

	if [ -z "$ifname" ] || [ -z "$vlanid" ]; then
		return
	fi

	local name="$ifname.$vlanid"

	uci -q set network.vlan_${vlanid}=device
	uci -q set network.vlan_${vlanid}.type="8021q"
	uci -q set network.vlan_${vlanid}.name="$name"
	uci -q set network.vlan_${vlanid}.ifname="$ifname"
	uci -q set network.vlan_${vlanid}.vid=$vlanid

	echo "$name"
}

create_vlan_interface() {
	local iface_name="$1"
	local ifname="$2"
	local vlanid="$3"
	local defaultroute="$4"
	local mgmt="$5"
	local device iface_name6

	if [ -z "$iface_name" ] || [ -z "$ifname" ]; then
		return
	fi

	# if not mgmt iface, then vlanid is mandatory
	if [ -n "$vlanid" ]; then
		device="$(create_vlan_dev "$ifname" "$vlanid")"
	elif [ "$mgmt" = "1" ]; then
		device="$ifname"
	else
		return
	fi

	if [ -n "$device" ]; then
		uci -q set network.$iface_name=interface
		uci -q set network.$iface_name.proto="dhcp"
		uci -q set network.$iface_name.device="$device"
		uci -q set network.$iface_name.defaultroute="$defaultroute"
		uci -q set network.$iface_name.reqopts="43"

		iface_name6="${iface_name}6"
		uci -q set network.$iface_name6=interface
		uci -q set network.$iface_name6.proto="dhcpv6"
		uci -q set network.$iface_name6.device="$device"
	fi
}

l3_dhcp_config() {
	# Enable DHCP Server
	uci -q set dhcp.lan.ignore=0
	uci -q set dhcp.wan.ignore=1
	uci -q set dhcp.$IPTV_IFACE=dhcp
	uci -q set dhcp.$IPTV_IFACE.interface="$IPTV_IFACE"
	uci -q set dhcp.$IPTV_IFACE.ignore=1
	uci -q set dhcp.$MGMT_IFACE=dhcp
	uci -q set dhcp.$MGMT_IFACE.interface="$MGMT_IFACE"
	uci -q set dhcp.$MGMT_IFACE.ignore=1
	uci -q commit dhcp
	/etc/init.d/odhcpd enable
}

l3_network_config() {
	logger -s -p user.info -t "netmode" "Generating L3 network configuration"

	local wandev="$(uci -q get network.WAN.ifname)"
	local new_wandev="$wandev"

	# Configure L3 Network Mode
	uci -q set network.lan=interface
	uci -q set network.lan.device='br-lan'
	uci -q set network.lan.proto='static'
	uci -q set network.lan.ipaddr='192.168.1.1'
	uci -q set network.lan.netmask='255.255.255.0'
	uci -q set network.lan.ip6assign='60'
	uci -q delete network.lan.vendorid
	uci -q delete network.lan.clientid
	uci -q delete network.lan.reqopts
	uci -q delete network.lan.sendopts

	uci -q delete network.lan6

	uci -q delete network.wan.disabled
	uci -q delete network.wan.username
	uci -q delete network.wan.password
	uci -q delete network.wan.ipaddr
	uci -q delete network.wan.gateway
	uci -q delete network.wan.netmask

	uci -q delete network.wan6.disabled

	# since inet_iface is supposed to have defaultroute set to 1, all traffic will flow through it
	# so using the default wan interface as inet_iface, as it is used as the default everywhere on the
	# system
	# inet_wan = wan
	# mgmt_wan = mgmt_wan
	# iptv_wan = iptv_wan
	create_vlan_interface "$MGMT_IFACE" "$wandev" "$NETMODE_mgmt_vlanid" "0" "1"
	create_vlan_interface "$INET_IFACE" "$wandev" "$NETMODE_inet_vlanid" "1" "0"
	create_vlan_interface "$IPTV_IFACE" "$wandev" "$NETMODE_iptv_vlanid" "0" "0"
	IPTV_DEV="$wandev.$NETMODE_iptv_vlanid"
	#TODO voice?

	[ -n "$NETMODE_mtu" ] && uci -q set network.WAN.mtu="$NETMODE_mtu"

	uci -q delete network.wan.dns
	if [ -n "$NETMODE_dns_servers" ]; then
		dns_servers="$(echo $NETMODE_dns_servers | tr ',' ' ')"
		for server in $dns_servers; do
		    uci -q add_list network.wan.dns=$server
		done
	fi

	uci -q delete network.br_lan.ports
	uci -q set network.br_lan.bridge_empty='1'

	add_port_to_br_lan() {
		port="$1"
		[ -n "$port" -a -d /sys/class/net/$port ] || continue
		uci add_list network.br_lan.ports="$port"
	}

	if [ -f /etc/board.json ]; then
		json_load_file /etc/board.json
		json_select network
		json_select lan
		if json_is_a ports array; then
			json_for_each_item add_port_to_br_lan ports
		else
			json_get_var device device
			[ -n "$device" ] && uci add_list network.br_lan.ports="$device"
		fi
		json_select ..
		json_cleanup
	fi

	uci -q commit network
}

l3_misc_config() {
	# Enable SSDPD
	uci -q set ssdpd.ssdp.enabled="1"
	uci -q commit ssdpd

	# Update CWMP Agent WAN Interface
	uci -q set cwmp.cpe.default_wan_interface="wan"
	uci -q commit cwmp

	# Update gateway WAN Interface
	uci -q set gateway.global.wan_interface="wan"
	uci -q commit gateway
}

l3_firewall_config() {
	# iptv_iface is for iptv
	# wan interface is for internet
	# mgmt_iface is for mgmt
	#
	# so service zone will have iptv_iface and wan_iface interface
	# so management zone will have mgmt_iface
	local iface
	local firewall_file="/etc/config/firewall"

	# Check if the file exists
	if [ ! -f "$firewall_file" ]; then
		echo "Error: $firewall_file does not exist."
		return 1
	fi

	logger -s -p user.info -t "netmode" "Configuring firewall"

	# Check if 'mgmt' zone already exists to avoid duplicates
	if grep -q "config zone 'mgmt'" "$firewall_file"; then
		echo "Firewall zone 'mgmt' already exists. Skipping append."
		return 0
	fi

	uci -q set firewall.globals.enabled="1"

	# iptv and inet interfaces replace existing wan interface in the firewall
	# as for mgmt, a separate zone will be created below, because lan traffic
	# is not forwarded to mgmt
	uci -q set firewall.wan.network=""
	for iface in "$INET_IFACE" "$INET_IFACE6" "$IPTV_IFACE" "$IPTV_IFACE6"; do
		uci -q add_list firewall.wan.network="$iface"
	done

	append_mgmt_firewall_config

	uci -q commit firewall
}

l3_network_config
l3_dhcp_config
l3_mcast_config "$IPTV_DEV"
l3_firewall_config
l3_misc_config

# If device is already boot-up, assume netmode changed during runtime
if [ -f /var/run/boot_complete ]; then
	/etc/init.d/odhcpd restart 2>/dev/null
	for config in network dhcp ssdpd cwmp gateway firewall mcast; do
		ubus call uci commit "{\"config\":\"$config\"}"
		sleep 1
	done
fi

