#!/bin/sh
#
# Media Flow Data Collector
# Collects streaming service data from netifyd and stores in history
#

HISTORY_FILE="/tmp/media-flow-history.json"
MAX_ENTRIES=1000
LOCK_FILE="/tmp/media-flow-collector.lock"

# Streaming services patterns
STREAMING_PATTERN="netflix|youtube|disney|primevideo|amazon.*video|twitch|hulu|hbo|vimeo|peacock|paramount|crunchyroll|funimation|spotify|apple.*music|deezer|soundcloud|tidal|pandora|amazon.*music|youtube.*music|zoom|teams|meet|discord|skype|webex|facetime|whatsapp"

# Check if already running
if [ -f "$LOCK_FILE" ]; then
	pid=$(cat "$LOCK_FILE")
	if kill -0 "$pid" 2>/dev/null; then
		exit 0
	fi
fi

echo $$ > "$LOCK_FILE"
trap "rm -f $LOCK_FILE" EXIT

# Check if enabled
enabled=$(uci -q get media_flow.global.enabled 2>/dev/null || echo "1")
[ "$enabled" != "1" ] && exit 0

# Check if netifyd is running
pgrep netifyd > /dev/null 2>&1 || exit 0

# Initialize history file
[ ! -f "$HISTORY_FILE" ] && echo '[]' > "$HISTORY_FILE"

# Get current flows from netifyd
if [ -f /var/run/netifyd/status.json ]; then
	timestamp=$(date -Iseconds)

	# Extract streaming flows and format as history entries
	new_entries=$(jq -c --arg ts "$timestamp" '
		.flows // [] |
		[.[] |
			select(.detected_application != null and .detected_application != "") |
			select(.detected_application | test("'"$STREAMING_PATTERN"'"; "i")) |
			{
				timestamp: $ts,
				app: .detected_application,
				client: (.local_ip // .src_ip // "unknown"),
				bandwidth: (if .total_packets > 0 and .duration > 0 then
					((.total_bytes * 8) / 1000 / .duration) | floor
				else 0 end),
				duration: (.duration // 0 | floor),
				quality: (if .total_packets > 0 and .duration > 0 then
					(if ((.total_bytes * 8) / 1000 / .duration) < 1000 then "SD"
					elif ((.total_bytes * 8) / 1000 / .duration) < 3000 then "HD"
					elif ((.total_bytes * 8) / 1000 / .duration) < 8000 then "FHD"
					else "4K" end)
				else "SD" end),
				category: (if (.detected_application | test("netflix|youtube|disney|primevideo|twitch|hulu|hbo|vimeo"; "i")) then "video"
					elif (.detected_application | test("spotify|apple.*music|deezer|soundcloud|tidal"; "i")) then "audio"
					elif (.detected_application | test("zoom|teams|meet|discord|skype|webex"; "i")) then "visio"
					else "other" end),
				bytes: (.total_bytes // 0)
			}
		] |
		# Only include flows with significant duration (> 10 seconds)
		[.[] | select(.duration > 10)]
	' /var/run/netifyd/status.json 2>/dev/null)

	# If we have new entries, merge with history
	if [ -n "$new_entries" ] && [ "$new_entries" != "[]" ] && [ "$new_entries" != "null" ]; then
		# Merge and deduplicate (by client+app combination within same minute)
		jq -c --argjson new "$new_entries" '
			. + $new |
			# Keep only last MAX_ENTRIES
			.[-'"$MAX_ENTRIES"':]
		' "$HISTORY_FILE" > "${HISTORY_FILE}.tmp" 2>/dev/null && mv "${HISTORY_FILE}.tmp" "$HISTORY_FILE"
	fi
fi

# Clean old entries based on retention (days)
retention=$(uci -q get media_flow.global.history_retention 2>/dev/null || echo "7")
if [ "$retention" -gt 0 ] 2>/dev/null; then
	cutoff_date=$(date -d "$retention days ago" -Iseconds 2>/dev/null || date -Iseconds)
	jq -c --arg cutoff "$cutoff_date" '[.[] | select(.timestamp >= $cutoff)]' "$HISTORY_FILE" > "${HISTORY_FILE}.tmp" 2>/dev/null && mv "${HISTORY_FILE}.tmp" "$HISTORY_FILE"
fi

exit 0
