#!/bin/sh
# Copyright 2023 MOSSDeF, Stan Grishin (stangri@melmac.ca)
# shellcheck disable=SC2018,SC2019,SC3043,SC3060

# TechRef: https://openwrt.org/docs/techref/rpcd
# TESTS
# ubus -v list luci.adblock-fast
# ubus -S call luci.adblock-fast getFileUrlFilesizes '{"name": "adblock-fast" }'
# ubus -S call luci.adblock-fast getInitList '{"name": "adblock-fast" }'
# ubus -S call luci.adblock-fast getInitStatus '{"name": "adblock-fast" }'
# ubus -S call luci.adblock-fast getPlatformSupport '{"name": "adblock-fast" }'
# ubus -S call luci.adblock-fast setInitAction '{"name": "adblock-fast", "action": "start" }'
# ubus -S call luci.adblock-fast setInitAction '{"name": "adblock-fast", "action": "dl" }'
# ubus -S call luci.adblock-fast setInitAction '{"name": "adblock-fast", "action": "pause" }'
# ubus -S call luci.adblock-fast setInitAction '{"name": "adblock-fast", "action": "stop" }'

readonly luciCompat='4'
readonly adbFunctionsFile='/etc/init.d/adblock-fast'
if [ -s "$adbFunctionsFile" ]; then
# shellcheck source=../../../../../adblock-fast/files/etc/init.d/adblock-fast
	. "$adbFunctionsFile"
else
	logger -t adblock-fast 'error' "adblock-fast init.d file ($adbFunctionsFile) not found!"
	print_json_string 'error' "adblock-fast init.d file ($adbFunctionsFile) not found!"
fi

get_file_url_filesizes() {
	_get_file_url_size() {
		local url size
		config_get url "$1" 'url'
		config_get size "$1" 'size'
		if [ -z "$size" ]; then
			size="$(get_url_filesize "$url")"
			uci_set "$name" "$1" 'size' "$size"
		fi
		json_add_object
		json_add_string 'url' "$url"
		json_add_int 'size' "$size"
		json_close_object
	}
	local name="$1" i
	json_init
	json_add_object "$name"
	json_add_array 'sizes'
	config_load "$name"
	config_foreach _get_file_url_size 'file_url'
	json_close_array
	json_close_object
	json_dump
	json_cleanup
	[ -n "$(uci_changes "$name")" ] && uci_commit "$name"
}

get_init_list() {
	local name
	name="$(basename "$1")"
	name="${name:-$packageName}"
	json_init
	json_add_object "$name"
	json_add_boolean 'enabled' "$(is_enabled "$name")"
	if is_running "$name"; then
		json_add_boolean 'running' '1'
	else
		json_add_boolean 'running' '0'
	fi
	json_close_object
	json_dump
	json_cleanup
}

set_init_action() {
	local name action="$2" cmd
	name="$(basename "$1")"
	name="${name:-$packageName}"
	if [ ! -f "/etc/init.d/$name" ]; then
		print_json_string 'error' 'Init script not found!'
		return
	fi
	case $action in
		enable)
			cmd="/etc/init.d/${name} ${action}"
			cmd="${cmd} && uci_set ${name} config enabled 1 && uci_commit $name"
		;;
		disable)
			cmd="/etc/init.d/${name} ${action}"
			cmd="${cmd} && uci_set ${name} config enabled 0 && uci_commit $name"
		;;
		start|stop|reload|restart|dl|pause)
			cmd="/etc/init.d/${name} ${action}"
		;;
	esac
	if [ -n "$cmd" ] && eval "$cmd" >/dev/null 2>&1; then
		print_json_bool "result" '1'
	else
		print_json_bool "result" '0'
	fi
}

get_init_status() {
	local name
	name="$(basename "$1")"
	name="${name:-$packageName}"
	local errors warnings ports dns outputFile outputCache outputGzip outputConfig
	local i j
# shellcheck disable=SC2034
	local compressed_cache_dir
	config_load "$name"
	config_get compressed_cache_dir 'config' 'compressed_cache_dir' '/etc'
	compressed_cache_dir="$(sanitize_dir "$compressed_cache_dir")"
	compressed_cache_dir="${compressed_cache_dir:-/etc}"
	if [ -n "$(uci_get "$packageName" 'config' 'dnsmasq_config_file_url')" ]; then
		dns="dnsmasq.conf"
	else
		dns="$(uci_get "$packageName" 'config' 'dns' 'dnsmasq.servers')"
	fi

	dns_set_output_values "$dns"

	json_init
	json_add_object  "$name"
	json_add_boolean 'enabled' "$(is_enabled "$name")"
	json_add_string 'status' "$(json 'get' 'status')"
	if is_running "$name"; then
		json_add_boolean 'running' '1'
	else
		json_add_boolean 'running' '0'
	fi
	json_add_string 'version' "$PKG_VERSION"
	errors="$(ubus_get_data errors)"
	json_add_array 'errors'
	if [ -n "$errors" ]; then
		for i in $errors; do
			if str_contains "$i" '|'; then
				error_extra="${i##*|}"
				error_id="${i%|*}"
			else
				error_id="$i"
				unset error_extra
			fi
			json_add_object
			json_add_string 'id' "$error_id"
			json_add_string 'extra' "$error_extra"
			json_close_object
		done
	fi
	json_close_array
	warnings="$(ubus_get_data warnings)"
	json_add_array 'warnings'
	if [ -n "$warnings" ]; then
		for i in $warnings; do
			if str_contains "$i" '|'; then
				error_extra="${i##*|}"
				error_id="${i%|*}"
			else
				error_id="$i"
				unset error_extra
			fi
			json_add_object
			json_add_string 'id' "$error_id"
			json_add_string 'extra' "$error_extra"
			json_close_object
		done
	fi
	if is_greater "${packageCompat:-0}" "${luciCompat:-0}"; then
		json_add_object
		json_add_string 'id' 'warningOutdatedLuciPackage'
		json_close_object
	elif is_greater "${luciCompat:-0}" "${packageCompat:-0}"; then
		json_add_object
		json_add_string 'id' 'warningOutdatedPrincipalPackage'
		json_close_object
	fi
	json_close_array

	ports="$(ubus_get_ports)"
	if [ -n "$ports" ]; then
		json_add_boolean 'force_dns_active' '1'
		json_add_array 'force_dns_ports'
			for i in $ports; do json_add_int '' "$i"; done
		json_close_array
	else
		json_add_boolean 'force_dns_active' '0'
	fi
	json_add_int 'entries' "$(ubus_get_data entries)"
	json_add_string 'dns' "$dns"
	json_add_string 'outputFile' "$outputFile"
	json_add_string 'outputCache' "$outputCache"
	json_add_string 'outputGzip' "$outputGzip"
	if [ -s "$outputFile" ]; then 
		json_add_boolean 'outputFileExists' '1'
	else
		json_add_boolean 'outputFileExists' '0'
	fi
	if [ -s "$outputCache" ]; then 
		json_add_boolean 'outputCacheExists' '1'
	else
		json_add_boolean 'outputCacheExists' '0'
	fi
	if [ -s "$outputGzip" ]; then 
		json_add_boolean 'outputGzipExists' '1'
	else
		json_add_boolean 'outputGzipExists' '0'
	fi
	json_add_array 'leds'
		for i in /sys/class/leds/*; do json_add_string '' "$(basename "$i")"; done
	json_close_array
	json_close_object
	json_dump
	json_cleanup
}

get_platform_support() {
	local name
	name="$(basename "$1")"
	name="${name:-$packageName}"
	json_init
	json_add_object "$name"
	if check_ipset; then
		json_add_boolean 'ipset_installed' '1'
	else
		json_add_boolean 'ipset_installed' '0'
	fi
	if check_nft; then
		json_add_boolean 'nft_installed' '1'
	else
		json_add_boolean 'nft_installed' '0'
	fi
	if check_dnsmasq; then
		json_add_boolean 'dnsmasq_installed' '1'
	else
		json_add_boolean 'dnsmasq_installed' '0'
	fi
	if check_dnsmasq_ipset; then
		json_add_boolean 'dnsmasq_ipset_support' '1'
	else
		json_add_boolean 'dnsmasq_ipset_support' '0'
	fi
	if check_dnsmasq_nftset; then
		json_add_boolean 'dnsmasq_nftset_support' '1'
	else
		json_add_boolean 'dnsmasq_nftset_support' '0'
	fi
	if check_smartdns; then
		json_add_boolean 'smartdns_installed' '1'
	else
		json_add_boolean 'smartdns_installed' '0'
	fi
	if check_smartdns_ipset; then
		json_add_boolean 'smartdns_ipset_support' '1'
	else
		json_add_boolean 'smartdns_ipset_support' '0'
	fi
	if check_smartdns_nftset; then
		json_add_boolean 'smartdns_nftset_support' '1'
	else
		json_add_boolean 'smartdns_nftset_support' '0'
	fi
	if check_unbound; then
		json_add_boolean 'unbound_installed' '1'
	else
		json_add_boolean 'unbound_installed' '0'
	fi
	json_add_array 'leds'
		for i in /sys/class/leds/*; do json_add_string '' "$(basename "$i")"; done
	json_close_array
	json_close_object
	json_dump
	json_cleanup
}

case "$1" in
	list)
		json_init
		json_add_object "getFileUrlFilesizes"
			json_add_string 'name' 'name'
		json_close_object
		json_add_object "getInitList"
			json_add_string 'name' 'name'
		json_close_object
		json_add_object "getInitStatus"
			json_add_string 'name' 'name'
		json_close_object
		json_add_object "getPlatformSupport"
			json_add_string 'name' 'name'
		json_close_object
		json_add_object "setInitAction"
			json_add_string 'name' 'name'
			json_add_string 'action' 'action'
		json_close_object
		json_dump
		json_cleanup
		;;
	call)
		case "$2" in
			getFileUrlFilesizes)
				read -r input
				json_load "$input"
				json_get_var name 'name'
				json_cleanup
				get_file_url_filesizes "$name"
				;;
			getInitList)
				read -r input
				json_load "$input"
				json_get_var name 'name'
				json_cleanup
				get_init_list "$name"
				;;
			getInitStatus)
				read -r input
				json_load "$input"
				json_get_var name 'name'
				json_cleanup
				get_init_status "$name"
				;;
			getPlatformSupport)
				read -r input
				json_load "$input"
				json_get_var name 'name'
				json_cleanup
				get_platform_support "$name"
				;;
			setInitAction)
				read -r input
				json_load "$input"
				json_get_var name 'name'
				json_get_var action 'action'
				json_cleanup
				set_init_action "$name" "$action"
				;;
		esac
	;;
esac