#!/bin/sh
# P2P Package Catalog API
# Returns local package feed as JSON for mesh distribution

echo "Content-Type: application/json"
echo "Access-Control-Allow-Origin: *"
echo "Access-Control-Allow-Methods: GET, OPTIONS"
echo ""

# Handle CORS preflight
if [ "$REQUEST_METHOD" = "OPTIONS" ]; then
	exit 0
fi

# Load P2P feed library
. /usr/lib/secubox/p2p-feed.sh 2>/dev/null

# Parse query string
parse_query() {
	local query="$QUERY_STRING"
	local key value

	# Initialize variables
	INFO_ONLY=""
	PACKAGE_FILTER=""

	# Parse key=value pairs
	while [ -n "$query" ]; do
		key="${query%%=*}"
		query="${query#*=}"
		value="${query%%&*}"
		query="${query#*&}"
		[ "$query" = "$value" ] && query=""

		case "$key" in
			info_only) INFO_ONLY="$value" ;;
			package) PACKAGE_FILTER="$value" ;;
		esac
	done
}

parse_query

# Get node info
NODE_ID=$(get_local_node_id)
NODE_NAME=$(get_local_node_name)
UPDATED=$(date -Iseconds 2>/dev/null || date '+%Y-%m-%dT%H:%M:%S')

# Check if feed sharing is enabled
if ! feed_sharing_enabled; then
	cat << EOF
{
	"error": "feed_sharing_disabled",
	"message": "Package feed sharing is disabled on this node",
	"node_id": "$NODE_ID",
	"node_name": "$NODE_NAME"
}
EOF
	exit 0
fi

# Check if feed exists
if ! feed_exists; then
	cat << EOF
{
	"error": "no_feed",
	"message": "No package feed found",
	"node_id": "$NODE_ID",
	"node_name": "$NODE_NAME"
}
EOF
	exit 0
fi

FEED_HASH=$(get_feed_hash)
PKG_COUNT=$(get_package_count)

# Info only mode - just return metadata
if [ "$INFO_ONLY" = "1" ]; then
	cat << EOF
{
	"node_id": "$NODE_ID",
	"node_name": "$NODE_NAME",
	"updated": "$UPDATED",
	"feed_hash": "$FEED_HASH",
	"package_count": $PKG_COUNT,
	"feed_url": "http://$(uci -q get network.lan.ipaddr || echo '192.168.255.1')/secubox-feed/"
}
EOF
	exit 0
fi

# Filter for specific package
if [ -n "$PACKAGE_FILTER" ]; then
	# Search for specific package in Packages file
	PACKAGES_JSON=$(awk -v pkg="$PACKAGE_FILTER" '
	BEGIN {
		found = 0
		first = 1
		printf "["
	}

	/^Package:/ {
		current_pkg = $2
		if (current_pkg == pkg) found = 1
		else found = 0
	}

	found && /^$/ {
		if (pkg_name != "") {
			if (!first) printf ","
			first = 0
			printf "\n{"
			printf "\"name\":\"%s\"", pkg_name
			printf ",\"version\":\"%s\"", pkg_version
			printf ",\"architecture\":\"%s\"", pkg_arch
			printf ",\"size\":%s", (pkg_size != "" ? pkg_size : "0")
			printf ",\"installed_size\":%s", (pkg_isize != "" ? pkg_isize : "0")
			if (pkg_sha256 != "") printf ",\"sha256\":\"%s\"", pkg_sha256
			if (pkg_depends != "") printf ",\"depends\":\"%s\"", pkg_depends
			if (pkg_desc != "") {
				gsub(/"/, "\\\"", pkg_desc)
				printf ",\"description\":\"%s\"", pkg_desc
			}
			if (pkg_filename != "") printf ",\"filename\":\"%s\"", pkg_filename
			printf "}"
		}
		pkg_name = pkg_version = pkg_arch = pkg_size = pkg_isize = ""
		pkg_sha256 = pkg_depends = pkg_desc = pkg_filename = ""
		found = 0
	}

	found && /^Package:/ { pkg_name = $2 }
	found && /^Version:/ { pkg_version = $2 }
	found && /^Architecture:/ { pkg_arch = $2 }
	found && /^Size:/ { pkg_size = $2 }
	found && /^Installed-Size:/ { pkg_isize = $2 }
	found && /^SHA256sum:/ { pkg_sha256 = $2 }
	found && /^Depends:/ {
		pkg_depends = $0
		sub(/^Depends: */, "", pkg_depends)
	}
	found && /^Description:/ {
		pkg_desc = $0
		sub(/^Description: */, "", pkg_desc)
	}
	found && /^Filename:/ { pkg_filename = $2 }

	END {
		printf "\n]"
	}
	' "$PACKAGES_FILE")

	cat << EOF
{
	"node_id": "$NODE_ID",
	"node_name": "$NODE_NAME",
	"updated": "$UPDATED",
	"feed_hash": "$FEED_HASH",
	"filter": "$PACKAGE_FILTER",
	"packages": $PACKAGES_JSON
}
EOF
	exit 0
fi

# Full package list
PACKAGES_JSON=$(packages_to_json)

cat << EOF
{
	"node_id": "$NODE_ID",
	"node_name": "$NODE_NAME",
	"updated": "$UPDATED",
	"feed_hash": "$FEED_HASH",
	"package_count": $PKG_COUNT,
	"feed_url": "http://$(uci -q get network.lan.ipaddr || echo '192.168.255.1')/secubox-feed/",
	"packages": $PACKAGES_JSON
}
EOF
