#!/bin/sh
#
# RPCD backend for SecuBox DNS Provider Manager
#

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

CONFIG="dns-provider"

case "$1" in
	list)
		json_init
		json_add_object "get_config"
		json_close_object
		json_add_object "list_records"
		json_close_object
		json_add_object "add_record"
			json_add_string "type" "string"
			json_add_string "subdomain" "string"
			json_add_string "target" "string"
			json_add_int "ttl" 0
		json_close_object
		json_add_object "remove_record"
			json_add_string "type" "string"
			json_add_string "subdomain" "string"
		json_close_object
		json_add_object "sync_records"
		json_close_object
		json_add_object "verify_record"
			json_add_string "fqdn" "string"
		json_close_object
		json_add_object "test_credentials"
		json_close_object
		json_add_object "acme_dns01"
			json_add_string "domain" "string"
		json_close_object
		json_dump
		;;

	call)
		handle_call() {
		case "$1" in
			get_config)
				json_init

				local enabled=$(uci -q get ${CONFIG}.main.enabled)
				local provider=$(uci -q get ${CONFIG}.main.provider)
				local zone=$(uci -q get ${CONFIG}.main.zone)

				json_add_string "enabled" "${enabled:-0}"
				json_add_string "provider" "${provider:-}"
				json_add_string "zone" "${zone:-}"

				# Provider-specific config (mask secrets)
				case "$provider" in
					ovh)
						json_add_object "provider_config"
							json_add_string "endpoint" "$(uci -q get ${CONFIG}.ovh.endpoint)"
							local ak=$(uci -q get ${CONFIG}.ovh.app_key)
							local as=$(uci -q get ${CONFIG}.ovh.app_secret)
							local ck=$(uci -q get ${CONFIG}.ovh.consumer_key)
							json_add_boolean "app_key_set" "$([ -n "$ak" ] && echo 1 || echo 0)"
							json_add_boolean "app_secret_set" "$([ -n "$as" ] && echo 1 || echo 0)"
							json_add_boolean "consumer_key_set" "$([ -n "$ck" ] && echo 1 || echo 0)"
						json_close_object
						;;
					gandi)
						json_add_object "provider_config"
							local gk=$(uci -q get ${CONFIG}.gandi.api_key)
							json_add_boolean "api_key_set" "$([ -n "$gk" ] && echo 1 || echo 0)"
						json_close_object
						;;
					cloudflare)
						json_add_object "provider_config"
							local ct=$(uci -q get ${CONFIG}.cloudflare.api_token)
							local cz=$(uci -q get ${CONFIG}.cloudflare.zone_id)
							json_add_boolean "api_token_set" "$([ -n "$ct" ] && echo 1 || echo 0)"
							json_add_string "zone_id" "${cz:-}"
						json_close_object
						;;
					*)
						json_add_object "provider_config"
						json_close_object
						;;
				esac

				json_dump
				;;

			list_records)
				local provider=$(uci -q get ${CONFIG}.main.provider)
				local zone=$(uci -q get ${CONFIG}.main.zone)

				if [ -z "$provider" ] || [ -z "$zone" ]; then
					json_init
					json_add_boolean "success" 0
					json_add_string "error" "DNS provider not configured"
					json_dump
					exit 0
				fi

				# Call dnsctl and capture raw API output
				local output=$(/usr/sbin/dnsctl list 2>/dev/null | grep -v '^\[')

				json_init
				json_add_boolean "success" 1
				json_add_string "provider" "$provider"
				json_add_string "zone" "$zone"
				json_add_string "raw" "$output"
				json_dump
				;;

			add_record)
				read -r input
				local type=$(echo "$input" | jsonfilter -e '@.type' 2>/dev/null)
				local subdomain=$(echo "$input" | jsonfilter -e '@.subdomain' 2>/dev/null)
				local target=$(echo "$input" | jsonfilter -e '@.target' 2>/dev/null)
				local ttl=$(echo "$input" | jsonfilter -e '@.ttl' 2>/dev/null)

				if [ -z "$type" ] || [ -z "$subdomain" ] || [ -z "$target" ]; then
					json_init
					json_add_boolean "success" 0
					json_add_string "error" "type, subdomain and target are required"
					json_dump
					exit 0
				fi

				local output=$(/usr/sbin/dnsctl add "$type" "$subdomain" "$target" "${ttl:-3600}" 2>&1)
				local code=$?

				json_init
				json_add_boolean "success" $((code == 0))
				json_add_string "output" "$output"
				json_dump
				;;

			remove_record)
				read -r input
				local type=$(echo "$input" | jsonfilter -e '@.type' 2>/dev/null)
				local subdomain=$(echo "$input" | jsonfilter -e '@.subdomain' 2>/dev/null)

				if [ -z "$type" ] || [ -z "$subdomain" ]; then
					json_init
					json_add_boolean "success" 0
					json_add_string "error" "type and subdomain are required"
					json_dump
					exit 0
				fi

				local output=$(/usr/sbin/dnsctl rm "$type" "$subdomain" 2>&1)
				local code=$?

				json_init
				json_add_boolean "success" $((code == 0))
				json_add_string "output" "$output"
				json_dump
				;;

			sync_records)
				local output=$(/usr/sbin/dnsctl sync 2>&1)
				local code=$?

				json_init
				json_add_boolean "success" $((code == 0))
				json_add_string "output" "$output"
				json_dump
				;;

			verify_record)
				read -r input
				local fqdn=$(echo "$input" | jsonfilter -e '@.fqdn' 2>/dev/null)

				if [ -z "$fqdn" ]; then
					json_init
					json_add_boolean "success" 0
					json_add_string "error" "fqdn is required"
					json_dump
					exit 0
				fi

				# Check DNS propagation against multiple resolvers
				json_init
				json_add_boolean "success" 1
				json_add_string "fqdn" "$fqdn"
				json_add_array "resolvers"

				for resolver in 1.1.1.1 8.8.8.8 9.9.9.9; do
					local result=$(nslookup "$fqdn" "$resolver" 2>/dev/null | grep "Address:" | tail -1 | awk '{print $2}')
					local resolved=0
					if [ -n "$result" ] && [ "$result" != "$resolver" ]; then
						resolved=1
					fi

					json_add_object ""
						json_add_string "resolver" "$resolver"
						json_add_boolean "resolved" "$resolved"
						json_add_string "result" "${result:-}"
					json_close_object
				done

				json_close_array
				json_dump
				;;

			test_credentials)
				local output=$(/usr/sbin/dnsctl test 2>&1)
				local code=$?

				json_init
				if [ $code -eq 0 ]; then
					json_add_boolean "success" 1
					json_add_string "message" "Credentials valid"
				else
					json_add_boolean "success" 0
					json_add_string "error" "$output"
				fi
				json_dump
				;;

			acme_dns01)
				read -r input
				local domain=$(echo "$input" | jsonfilter -e '@.domain' 2>/dev/null)

				if [ -z "$domain" ]; then
					json_init
					json_add_boolean "success" 0
					json_add_string "error" "domain is required"
					json_dump
					exit 0
				fi

				local output=$(/usr/sbin/dnsctl acme-dns01 "$domain" 2>&1)
				local code=$?

				json_init
				json_add_boolean "success" $((code == 0))
				json_add_string "output" "$output"
				json_dump
				;;

			*)
				json_init
				json_add_boolean "error" 1
				json_add_string "message" "Unknown method: $1"
				json_dump
				;;
		esac
		}
		handle_call "$2"
		;;
esac

exit 0
