#!/bin/sh
#
# RPCD backend for SecuBox Device Intelligence
#

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

DI_LIB="/usr/lib/secubox/device-intel"
DI_CACHE="/tmp/device-intel"
CONFIG="device-intel"

case "$1" in
	list)
		json_init
		json_add_object "get_devices"
		json_close_object
		json_add_object "get_device"
			json_add_string "mac" "string"
		json_close_object
		json_add_object "get_summary"
		json_close_object
		json_add_object "get_mesh_devices"
		json_close_object
		json_add_object "get_emulators"
		json_close_object
		json_add_object "get_device_types"
		json_close_object
		json_add_object "classify_device"
			json_add_string "mac" "string"
		json_close_object
		json_add_object "set_device_meta"
			json_add_string "mac" "string"
			json_add_string "type" "string"
			json_add_string "label" "string"
		json_close_object
		json_add_object "refresh"
		json_close_object
		json_dump
		;;

	call)
		handle_call() {
		case "$1" in
			get_devices)
				. "${DI_LIB}/functions.sh"
				local devices=$(di_get_devices)

				# Stream directly — devices is already JSON array
				printf '{"success":true,"devices":%s}' "$devices"
				;;

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

				if [ -z "$mac" ]; then
					echo '{"success":false,"error":"mac is required"}'
					exit 0
				fi

				. "${DI_LIB}/functions.sh"
				local devices=$(di_get_devices)
				local mac_lower=$(echo "$mac" | tr 'A-F' 'a-f')

				# Extract single device from array
				local device=$(echo "$devices" | jsonfilter -e "@[@.mac='${mac_lower}']" 2>/dev/null)

				if [ -n "$device" ]; then
					printf '{"success":true,"device":%s}' "$device"
				else
					echo '{"success":false,"error":"Device not found"}'
				fi
				;;

			get_summary)
				. "${DI_LIB}/functions.sh"
				local summary=$(di_get_summary)

				# Add emulator counts
				local usb_enabled=$(uci -q get ${CONFIG}.usb.enabled)
				local mqtt_enabled=$(uci -q get ${CONFIG}.mqtt.enabled)
				local zigbee_enabled=$(uci -q get ${CONFIG}.zigbee.enabled)

				# Count data sources
				local mg_available=0
				[ -f /var/run/mac-guardian/known.db ] && mg_available=1
				local cg_available=0
				uci -q get client-guardian.@client[0] >/dev/null 2>&1 && cg_available=1
				local dhcp_available=0
				[ -f /tmp/dhcp.leases ] && dhcp_available=1
				local p2p_running=0
				pgrep -f secubox-p2p >/dev/null 2>&1 && p2p_running=1

				# Build response
				local total=$(echo "$summary" | jsonfilter -e '@.total' 2>/dev/null)
				local online=$(echo "$summary" | jsonfilter -e '@.online' 2>/dev/null)
				local mesh=$(echo "$summary" | jsonfilter -e '@.mesh_peers' 2>/dev/null)

				json_init
				json_add_boolean "success" 1
				json_add_int "total" "${total:-0}"
				json_add_int "online" "${online:-0}"
				json_add_int "mesh_peers" "${mesh:-0}"

				json_add_object "emulators"
					json_add_boolean "usb" "$([ "$usb_enabled" = "1" ] && echo 1 || echo 0)"
					json_add_boolean "mqtt" "$([ "$mqtt_enabled" = "1" ] && echo 1 || echo 0)"
					json_add_boolean "zigbee" "$([ "$zigbee_enabled" = "1" ] && echo 1 || echo 0)"
				json_close_object

				json_add_object "sources"
					json_add_boolean "mac_guardian" "$mg_available"
					json_add_boolean "client_guardian" "$cg_available"
					json_add_boolean "dhcp" "$dhcp_available"
					json_add_boolean "p2p" "$p2p_running"
				json_close_object

				json_dump
				;;

			get_mesh_devices)
				. "${DI_LIB}/functions.sh"
				local devices=$(di_get_devices)

				# Filter mesh devices
				printf '{"success":true,"devices":['
				local first=1
				echo "$devices" | jsonfilter -e '@[*]' 2>/dev/null | while read -r dev; do
					local src=$(echo "$dev" | jsonfilter -e '@.source_node' 2>/dev/null)
					local dtype=$(echo "$dev" | jsonfilter -e '@.device_type' 2>/dev/null)
					if [ "$src" = "mesh" ] || [ "$dtype" = "mesh_peer" ]; then
						[ $first -eq 1 ] && first=0 || printf ','
						echo "$dev"
					fi
				done
				printf ']}'
				;;

			get_emulators)
				json_init
				json_add_boolean "success" 1

				# USB
				json_add_object "usb"
					json_add_boolean "enabled" "$([ "$(uci -q get ${CONFIG}.usb.enabled)" = "1" ] && echo 1 || echo 0)"
					json_add_int "scan_interval" "$(uci -q get ${CONFIG}.usb.scan_interval || echo 120)"
					local usb_count=$(ls -d /sys/bus/usb/devices/[0-9]* 2>/dev/null | grep -v ':' | wc -l)
					json_add_int "device_count" "$usb_count"
				json_close_object

				# MQTT
				json_add_object "mqtt"
					json_add_boolean "enabled" "$([ "$(uci -q get ${CONFIG}.mqtt.enabled)" = "1" ] && echo 1 || echo 0)"
					json_add_string "broker_host" "$(uci -q get ${CONFIG}.mqtt.broker_host)"
					json_add_int "broker_port" "$(uci -q get ${CONFIG}.mqtt.broker_port || echo 1883)"
					local mqtt_running=0
					pgrep mosquitto >/dev/null 2>&1 && mqtt_running=1
					json_add_boolean "broker_running" "$mqtt_running"
				json_close_object

				# Zigbee
				json_add_object "zigbee"
					json_add_boolean "enabled" "$([ "$(uci -q get ${CONFIG}.zigbee.enabled)" = "1" ] && echo 1 || echo 0)"
					json_add_string "adapter" "$(uci -q get ${CONFIG}.zigbee.adapter)"
					json_add_string "coordinator" "$(uci -q get ${CONFIG}.zigbee.coordinator)"
					local dongle_present=0
					local coord=$(uci -q get ${CONFIG}.zigbee.coordinator)
					[ -c "${coord:-/dev/ttyUSB0}" ] 2>/dev/null && dongle_present=1
					json_add_boolean "dongle_present" "$dongle_present"
				json_close_object

				json_dump
				;;

			get_device_types)
				. "${DI_LIB}/functions.sh"
				local types=$(di_get_device_types)
				printf '{"success":true,"types":%s}' "$types"
				;;

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

				. "${DI_LIB}/functions.sh"
				. "${DI_LIB}/classify.sh"

				if [ -n "$mac" ]; then
					local output=$(/usr/sbin/device-intelctl classify "$mac" 2>&1)
				else
					local output=$(/usr/sbin/device-intelctl classify 2>&1)
				fi

				json_init
				json_add_boolean "success" 1
				json_add_string "output" "$output"
				json_dump
				;;

			set_device_meta)
				read -r input
				local mac=$(echo "$input" | jsonfilter -e '@.mac' 2>/dev/null)
				local dtype=$(echo "$input" | jsonfilter -e '@.type' 2>/dev/null)
				local label=$(echo "$input" | jsonfilter -e '@.label' 2>/dev/null)

				if [ -z "$mac" ]; then
					echo '{"success":false,"error":"mac is required"}'
					exit 0
				fi

				local mac_lower=$(echo "$mac" | tr 'A-F' 'a-f')
				local mac_clean=$(echo "$mac_lower" | tr -d ':')

				# Create/update UCI section
				uci set ${CONFIG}.${mac_clean}=device
				uci set ${CONFIG}.${mac_clean}.mac="$mac_lower"
				[ -n "$dtype" ] && uci set ${CONFIG}.${mac_clean}.type="$dtype"
				[ -n "$label" ] && uci set ${CONFIG}.${mac_clean}.label="$label"
				uci commit "$CONFIG"

				# Invalidate cache
				rm -f "${DI_CACHE}"/cache*.json 2>/dev/null

				json_init
				json_add_boolean "success" 1
				json_add_string "message" "Device metadata updated"
				json_dump
				;;

			refresh)
				rm -f "${DI_CACHE}"/cache*.json 2>/dev/null

				json_init
				json_add_boolean "success" 1
				json_add_string "message" "Cache invalidated"
				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
