#!/bin/sh
set -u

: "${EDITOR:=vi}"
export EDITOR

BLACK="\033[1;30m"
RED="\033[1;31m"
GREEN="\033[1;32m"
YELLOW="\033[1;33m"
BLUE="\033[1;34m"
MAGENTA="\033[1;35m"
CYAN="\033[1;36m"
WHITE="\033[1;37m"
RESET="\033[0m"

BOOT="/boot"
OTA="${BOOT}/ota"
PLAYING_FILE="/home/signage/playing.json"
LOCATION_FILE="/home/signage/location"

print_line() {
	printf "%b%20s:%b %b%s%b\n" "$BLACK" "$1" "$RESET" "$2" "$3" "$RESET"
}

read_file() {
	local file="$1"

	[ -f "$file" ] || return 1
	tr -d '\0\n' < "$file"
}

read_json() {
	local key="$1"

	[ -f "$PLAYING_FILE" ] || {
		printf "unknown"
		return
	}

	jq --raw-output --arg key "$key" '.[$key] // "unknown"' "$PLAYING_FILE" 2>/dev/null
}

# Header
SUBDOMAIN="$(printf "%s" "${HOSTNAME:-isignage}" | awk '{print tolower(substr($0,1,1)) toupper(substr($0,2))}')"

printf "%b" "$WHITE"
figlet "$SUBDOMAIN"
printf "%bCopyright (c) 2015-2026 Microworks Limited\n" "$BLACK"
printf "Under License. All Rights Reserved\n"
printf "%b\n" "$RESET"

# Device
DEVICE="$(read_file /sys/firmware/devicetree/base/model 2>/dev/null || printf "Unknown Device")"
MEMORY="$(revision --memory 2>/dev/null || printf "Unknown Memory")"

print_line "Device" "$WHITE" "${DEVICE} ${MEMORY}"

# Serial / Machine ID
SERIAL="$(read_file /sys/firmware/devicetree/base/serial-number 2>/dev/null | awk '{print toupper($0)}')"

if [ -n "$SERIAL" ]; then
	print_line "Serial Number" "$RED" "└ ${SERIAL}"
else
	MACHINE_ID="$(read_file /var/lib/dbus/machine-id 2>/dev/null | awk '{print toupper($0)}')"
	print_line "MachineID" "$RED" "${MACHINE_ID:-unknown}"
fi

# CPU scaling
PRESENT="$(read_file /sys/devices/system/cpu/present 2>/dev/null || true)"

if [ -n "$PRESENT" ]; then
	printf "%b%20s:%b %b" "$BLACK" "Processor Speed(s)" "$RESET" "$MAGENTA"

	END="${PRESENT#0-}"

	for ((i = 0; i <= END; i++)); do
		CPU="$(read_file "/sys/devices/system/cpu/cpu${i}/cpufreq/scaling_cur_freq" 2>/dev/null || true)"

		if [ -n "$CPU" ]; then
			printf "%sMHz, " "$((CPU / 1000))"
		fi
	done

	printf "\b\b %bScaling%b " "$BLACK" "$WHITE"

	GOVERNOR="$(read_file /sys/devices/system/cpu/cpufreq/policy0/scaling_governor 2>/dev/null || true)"
	MIN="$(read_file /sys/devices/system/cpu/cpufreq/policy0/scaling_min_freq 2>/dev/null || true)"
	MAX="$(read_file /sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq 2>/dev/null || true)"

	if [ -n "$GOVERNOR" ]; then
		printf "%s" "$GOVERNOR"

		if [ -n "$MIN" ] && [ -n "$MAX" ]; then
			printf " %b(%sMHz - %sMHz)" "$BLACK" "$((MIN / 1000))" "$((MAX / 1000))"
		fi
	fi

	printf "%b\n" "$RESET"
fi

# Temperatures
printf "%b%20s:%b %b" "$BLACK" "Temperature(s)" "$RESET" "$MAGENTA"

FOUND_TEMP="0"

for ((i = 0; i < 5; i++)); do
	TEMP="$(read_file "/sys/class/thermal/thermal_zone${i}/temp" 2>/dev/null || true)"

	if [ -n "$TEMP" ]; then
		FOUND_TEMP="1"
		printf "%s.%s'C, " "$((TEMP / 1000))" "$(((TEMP / 100) % 10))"
	fi
done

if [ "$FOUND_TEMP" = "1" ]; then
	printf "\b\b "
else
	printf "unknown"
fi

printf "%b\n" "$RESET"

# Network
for INTERFACE_PATH in /sys/class/net/*; do
	[ -d "$INTERFACE_PATH" ] || continue

	NIC="$(basename "$INTERFACE_PATH")"
	OPERSTATE="$(read_file "${INTERFACE_PATH}/operstate" 2>/dev/null || true)"

	[ "$OPERSTATE" = "up" ] || continue

	MAC="$(read_file "/sys/class/net/${NIC}/address" 2>/dev/null | awk '{print toupper($0)}')"
	IPV4="$(ip -4 -o addr show dev "$NIC" 2>/dev/null | awk '{split($4,a,"/"); print a[1]}' | head -n 1)"
	IPV6="$(ip -6 -o addr show dev "$NIC" 2>/dev/null | awk '{split($4,a,"/"); print toupper(a[1])}' | head -n 1)"

	printf "%b%20s:%b %b%s%b\n  " "$BLACK" "$NIC" "$RESET" "$BLUE" "${MAC:-unknown}" "$RESET"
	printf "%b%20s:%b %b%s%b\n  " "$BLACK" "IPv4 ├" "$RESET" "$BLUE" "${IPV4:-none}" "$RESET"
	printf "%b%20s:%b %b%s%b\n" "$BLACK" "IPv6 └" "$RESET" "$BLUE" "${IPV6:-none}" "$RESET"
done

# Build
BUILD="$(awk -F= '$1=="VERSION"{gsub(/"/,"",$2); print $2}' /etc/os-release 2>/dev/null)"
print_line "Build" "$WHITE" "${BUILD:-unknown}"

# Playing
ACCOUNT="$(read_json account)"
BRANCH="$(read_json branch)"
PLAYLIST="$(read_json playlist)"
LOCATION="$(read_file "$LOCATION_FILE" 2>/dev/null || printf "unknown")"

print_line "Account" "$GREEN" "$ACCOUNT"
print_line "Branch" "$GREEN" "$BRANCH"
print_line "Location" "$GREEN" "$LOCATION"
print_line "Playlist" "$GREEN" "$PLAYLIST"

# Uptime
UPTIME_RAW="$(awk '{print int($1)}' /proc/uptime 2>/dev/null || printf "0")"
SECONDS="$((UPTIME_RAW % 60))"
MINUTES="$((UPTIME_RAW / 60 % 60))"
HOURS="$((UPTIME_RAW / 3600 % 24))"
DAYS="$((UPTIME_RAW / 86400))"

print_line "Uptime" "$YELLOW" "${DAYS} Day(s), ${HOURS} Hour(s), ${MINUTES} Minute(s), ${SECONDS} Second(s)"

# OTA / rollback status
ACTIVE_ROOT="$(findmnt -n -o SOURCE / 2>/dev/null || printf "unknown")"
print_line "Active Root" "$BLUE" "$ACTIVE_ROOT"

if [ -f "$OTA/pending-root" ]; then
	PENDING="$(read_file "$OTA/pending-root" 2>/dev/null || printf "unknown")"
	print_line "Pending Root" "$YELLOW" "$PENDING"
else
	print_line "Pending Root" "$GREEN" "none"
fi

if [ -f "$BOOT/rollback.flag" ]; then
	print_line "Rollback Flag" "$RED" "PRESENT"
else
	print_line "Rollback Flag" "$GREEN" "clear"
fi

if [ -f "$OTA/last-failed-root" ]; then
	LAST_FAILED="$(read_file "$OTA/last-failed-root" 2>/dev/null || printf "unknown")"
	print_line "Last Failed Root" "$RED" "$LAST_FAILED"
fi

if [ -f "$OTA/report/partition-repair-result" ]; then
	RESULT="$(read_file "$OTA/report/partition-repair-result" 2>/dev/null || printf "unknown")"

	case "$RESULT" in
		success) RESULT_COLOR="$GREEN" ;;
		failed)  RESULT_COLOR="$RED" ;;
		*)       RESULT_COLOR="$YELLOW" ;;
	esac

	print_line "Partition Repair" "$RESULT_COLOR" "$RESULT"
fi

if [ -f "$OTA/report/partition-repair-reason" ]; then
	REASON="$(read_file "$OTA/report/partition-repair-reason" 2>/dev/null || printf "unknown")"
	print_line "Repair Reason" "$YELLOW" "$REASON"
fi

if [ -f "$OTA/report/partition-repair-started-at" ]; then
	STARTED="$(read_file "$OTA/report/partition-repair-started-at" 2>/dev/null || printf "unknown")"
	print_line "Repair Started" "$BLUE" "$STARTED"
fi

printf "%b\n" "$RESET"
