#!/bin/sh

. /usr/share/libubox/jshn.sh

BBFDM_CONFIG_CONFDIR="/etc/config"
BBFDM_DMMAP_CONFDIR="/etc/bbfdm/dmmap"
BBFDM_CONFIG_SAVEDIR="/tmp/bbfdm/.bbfdm/config"
BBFDM_DMMAP_SAVEDIR="/tmp/bbfdm/.bbfdm/dmmap"

LOGLEVEL="$(uci -q get bbfdm.bbfdmd.loglevel)"

log() {
	local level

	level="${LOGLEVEL:-0}"
	if [ "${level}" -gt 2 ]; then
		echo "$@" | logger -t bbf.config -p info
	fi
}

check_result() {
	local res="$1"
	local service="$2"
	local action="$3"

	if [ "${res}" -ne 0 ]; then
		echo "{ \"error\": \"Failed to ${action} ${service} service\" }"
		exit "${res}"
	fi
}

apply_config_changes() {
	local service="$1"
	local action="$3"
	local reload="$4"

	# Check if either service or action is empty
	if [ -z "$service" ] || [ -z "$action" ]; then
		return
	fi
	
	log "Applying $action configuration for service: $service"
	
	# Commit/Revert config changes
	log "Applying ${action} configuration for file: ${service}"
	uci -q -c "${BBFDM_CONFIG_CONFDIR}" -t "${BBFDM_CONFIG_SAVEDIR}" "${action}" "${service}"
	check_result "$?" "${service}" "${action}"

	if [ "${reload}" == "1" ]; then
		# Reload service
		ubus -t 1 call uci "${action}" "{'config': '${service}'}"
		check_result "$?" "${service}" "${action}"	
	fi
}

case "$1" in
	list)
		echo '{ "commit": { "services": [], "proto": "str", "monitor": true, "reload": true }, "revert": { "services": [], "proto": "str", "monitor": true, "reload": true }, "changes": { "proto": "str" } }'
	;;
	call)
		# Read input JSON from standard input
		read -r input

		# Parse input JSON
		json_load "${input}"

		# Get the 'proto' value from the input JSON
		json_get_var proto proto

		if [ "${proto}" == "cwmp" ]; then
			BBFDM_CONFIG_SAVEDIR="/tmp/bbfdm/.cwmp/config"
			BBFDM_DMMAP_SAVEDIR="/tmp/bbfdm/.cwmp/dmmap"
		elif [ "${proto}" == "usp" ]; then
			BBFDM_CONFIG_SAVEDIR="/tmp/bbfdm/.usp/config"
			BBFDM_DMMAP_SAVEDIR="/tmp/bbfdm/.usp/dmmap"		
		fi

		case "$2" in
			commit|revert)

				# Get the 'reload' value from the input JSON
				json_get_var reload reload
				json_get_var monitor monitor
		
				if [ -z "${reload}" ]; then
					reload=1
				else
					if [ "${reload}" != "0" ] && [ "${reload}" != "1" ]; then
						echo '{ "error": "Reload should be boolean type !!!" }'
						exit 1		
					fi
				fi

				# Check if 'services' array is provided
				json_get_type type "services"
				if [ -z "${type}" ]; then
					# Iterate over all services and apply config changes
					for config in $(uci -q -c "${BBFDM_CONFIG_CONFDIR}" -t "${BBFDM_CONFIG_SAVEDIR}" changes | awk -F'.' '{print $1}' | sort | uniq); do
						apply_config_changes "${config}" "" "$2" "$reload"
					done
				else
					# Check if 'services' is array
					if [ "${type}" != "array" ]; then
						echo '{ "error": "Services argument should be array of strings !!!" }'
						exit 1
					fi

					# Iterate over each service and apply config changes
					json_for_each_item "apply_config_changes" "services" "$2" "$reload"
				fi

				if [ "${reload}" == "1" ]; then
					# Commit/Revert bbfdm dmmap config changes
					if [ -d "${BBFDM_DMMAP_SAVEDIR}" ] && [ "$(ls -A "${BBFDM_DMMAP_SAVEDIR}" 2>/dev/null)" ]; then
						for file in "${BBFDM_DMMAP_SAVEDIR}"/*; do
							file_name=$(basename "${file}")
							log "Applying $2 configuration for file: $file_name"
							uci -q -c "${BBFDM_DMMAP_CONFDIR}" -t "${BBFDM_DMMAP_SAVEDIR}" "$2" "${file_name}"
							check_result "$?" "${file_name}" "$2"
						done
					fi		
				fi

				if [ "${monitor}" -eq "1" ]; then
					sleep 3
				fi

				# Send 'bbf.config.change' event to run refresh instances
				ubus send bbf.config.change

				echo '{ "status": "ok" }'
			;;
			changes)
				json_init
				json_add_array "configs"
				for config in $(uci -q -c "${BBFDM_CONFIG_CONFDIR}" -t "${BBFDM_CONFIG_SAVEDIR}" changes | awk -F'.' '{print $1}' | sort | uniq); do
					json_add_string "" "${config}"
				done
				json_close_array
				json_dump
			;;
		esac
	;;
esac
