#!/bin/sh

. /lib/functions.sh

generate_igmp_global_params(){
	uci add mcast igmp
	uci rename mcast.@igmp[-1]="igmp"
	uci set mcast.@igmp[-1].max_membership="20"
	uci set mcast.@igmp[-1].max_msf="10"
	uci set mcast.@igmp[-1].qrv="2"
	uci set mcast.@igmp[-1].force_version="0"

	uci add mcast mld
	uci rename mcast.@mld[-1]="mld"
	uci set mcast.@mld[-1].mldv1_unsolicited_report_interval="10"
	uci set mcast.@mld[-1].mldv2_unsolicited_report_interval="1"
	uci set mcast.@mld[-1].qrv="2"
	uci set mcast.@mld[-1].force_version="0"
}

generate_mld_proxy_config(){
	local u_itf="$1"

	uci add mcast proxy
	uci rename mcast.@proxy[-1]="mc_proxy_MLD"
	uci set mcast.@proxy[-1].enable="1"
	uci set mcast.@proxy[-1].proto="mld"
	uci set mcast.@proxy[-1].version="2"
	uci set mcast.@proxy[-1].robustness="2"
	uci set mcast.@proxy[-1].query_interval="125"
	uci set mcast.@proxy[-1].query_response_interval="100"
	uci set mcast.@proxy[-1].last_member_query_interval="10"
	uci set mcast.@proxy[-1].fast_leave="1"
	uci set mcast.@proxy[-1].snooping_mode="2"
	uci add_list mcast.@proxy[-1].downstream_interface="br-lan"

	IFS=" "
	for itf in $u_itf; do
		uci add_list mcast.@proxy[-1].upstream_interface="$itf"
	done

}

generate_igmp_proxy_config(){
	local u_itf="$1"

	uci add mcast proxy
	uci rename mcast.@proxy[-1]="igmp_proxy_1"
	uci set mcast.@proxy[-1].enable="1"
	uci set mcast.@proxy[-1].proto="igmp"
	uci set mcast.@proxy[-1].version="2"
	uci set mcast.@proxy[-1].robustness="2"
	uci set mcast.@proxy[-1].query_interval="125"
	uci set mcast.@proxy[-1].query_response_interval="100"
	uci set mcast.@proxy[-1].last_member_query_interval="10"
	uci set mcast.@proxy[-1].fast_leave="1"
	uci set mcast.@proxy[-1].snooping_mode="2"
	uci add_list mcast.@proxy[-1].downstream_interface="br-lan"

	IFS=" "
	for itf in $u_itf; do
		uci add_list mcast.@proxy[-1].upstream_interface="$itf"
	done

	uci add_list mcast.@proxy[-1].filter="239.0.0.0/8"
}

generate_mld_snooping_config(){
	local u_itf="$1"

	uci add mcast snooping
	uci rename mcast.@snooping[-1]="mc_snooping_MLD"
	uci set mcast.@snooping[-1].enable="1"
	uci set mcast.@snooping[-1].proto="mld"
	uci set mcast.@snooping[-1].version="2"
	uci set mcast.@snooping[-1].robustness="2"
	uci set mcast.@snooping[-1].query_interval="125"
	uci set mcast.@snooping[-1].query_response_interval="100"
	uci set mcast.@snooping[-1].last_member_query_interval="10"
	uci set mcast.@snooping[-1].fast_leave="1"
	uci set mcast.@snooping[-1].snooping_mode="2"
	uci set mcast.@snooping[-1].interface="$u_itf"
}

generate_igmp_snooping_config(){
	local u_itf="$1"

	uci add mcast snooping
	uci rename mcast.@snooping[-1]="igmp_snooping_1"
	uci set mcast.@snooping[-1].enable="1"
	uci set mcast.@snooping[-1].proto="igmp"
	uci set mcast.@snooping[-1].version="2"
	uci set mcast.@snooping[-1].robustness="2"
	uci set mcast.@snooping[-1].query_interval="125"
	uci set mcast.@snooping[-1].query_response_interval="100"
	uci set mcast.@snooping[-1].last_member_query_interval="10"
	uci set mcast.@snooping[-1].fast_leave="1"
	uci set mcast.@snooping[-1].snooping_mode="2"
	uci set mcast.@snooping[-1].interface="$u_itf"

	uci add_list mcast.@snooping[-1].filter="239.0.0.0/8"
}

check_wan_bridge() {
	local config="$1"
	local wan_device="$2"
	local name type

	[ $((is_wan_bridge)) -ne 0 ] && return

	config_get type "$config" type
	config_get name "$config" name

	[ "$type" = "bridge" -a "$wan_device" = "$name" ] && is_wan_bridge=1
}

generate_mcast_config(){
	local up_itf="$(uci -q get network.wan.device)"
	local is_wan_bridge=0

	config_load network
	config_foreach check_wan_bridge device "$up_itf"

	if [ $((is_wan_bridge)) -eq 0 ]; then
		generate_igmp_proxy_config "$up_itf"
		generate_mld_proxy_config "$up_itf"
	else
		generate_igmp_snooping_config "$up_itf"
		generate_mld_snooping_config "$up_itf"
	fi
}

interfaces_ok(){
	local section_name=$1

	local up_interf=$(uci -q get ${section_name}.upstream_interface)
	[ -z "$up_interf" ] && return 1

	local down_interf=$(uci -q get ${section_name}.downstream_interface)
	[ -z "$down_interf" ] && return 1

	# check if upstream untagged
	IFS=" "
	for itf in $up_interf; do
		# check if there exist a interface section for this upstream interface, if yes the
		# do nothing, if no then generate config as mcast config is outdated
		local dev_section=$(uci show network | grep -E "\.device=\'$itf\'" | head -n 1 | cut -d'.' -f2)

		# mcast config is outdated, simply generate as per new logic
		if [ -z "$dev_section" ]; then
		       # check if the itf is a native interface	&& return 1
			return 1
		else
			section_type=$(uci get network.$dev_section)
			if [ "$section_type" == "interface" ]; then
				# interface section exits, hence, sync has already happened
				# nothing to do further, just return
				return 0
			else
				# mcast config is outdated
				return 1
			fi
		fi
	done
	return 0
}


if [ -s "/etc/config/mcast" ]; then
	if uci -q get mcast.@proxy[0] >/dev/null; then
		interfaces_ok "mcast.@proxy[0]" && exit
	elif uci -q get mcast.@snooping[0] >/dev/null; then
		# return if there is any valid content
		exit
	fi
fi

rm -f /etc/config/mcast
touch /etc/config/mcast

generate_igmp_global_params

generate_mcast_config
