#!/usr/bin/env bash

readonly SCRIPT_NAME="limine-snapper-notify"
readonly TITLE=""
readonly LOG_LEVEL=3

# Load key=value config
load_key_value_config() {
	local file="$1"
	[[ ! -f "$file" ]] && return

	while IFS='=' read -r key val || [[ -n "$key" ]]; do
		# Skip blank lines or lines starting with #
		[[ -z "$key" || "$key" =~ ^[[:space:]]*# ]] && continue

		# Trim spaces around key and value
		key="${key//[[:space:]]/}"
		val="${val#"${val%%[![:space:]]*}"}" # left trim
		val="${val%"${val##*[![:space:]]}"}" # right trim
		val="${val%\"}"                      # remove trailing quote
		val="${val#\"}"                      # remove leading quote

		export "$key"="$val"
	done <"$file"
}

# Load configuration
load_config() {
	local config_files=(
		/etc/limine-snapper-sync.conf
		/etc/default/limine
		/tmp/limine-snapper-sync.conf
	)
	for file in "${config_files[@]}"; do
		[[ -f "$file" ]] && load_key_value_config "$file"
	done

	# Set defaults if not already defined
	ENABLE_NOTIFICATION="${ENABLE_NOTIFICATION:-yes}"
	NOTIFICATION_ICON="${NOTIFICATION_ICON:-/usr/share/icons/hicolor/128x128/apps/LimineSnapperSync.png}"
}

# Notify using dunstify or notify-send
notify_user() {
	local msg="$1" action=""
	if command -v dunstify &>/dev/null; then
		action=$(dunstify -u critical --appname="$SCRIPT_NAME" \
			--icon="$NOTIFICATION_ICON" \
			--action="disableAction,Disable" \
			--action="closeAction,Close" \
			"$TITLE" "$msg" -t 0)
	elif command -v notify-send &>/dev/null; then
		action=$(notify-send -u critical --app-name="$SCRIPT_NAME" \
			--icon="$NOTIFICATION_ICON" \
			--action="disableAction=Disable" \
			--action="closeAction=Close" \
			"$TITLE" "$msg" -t 0)
	else
		echo -e "\033[91mlibnotify or dunst is not installed.\033[0m" >&2
		logger -t "$SCRIPT_NAME" -p err "libnotify or dunst is not installed."
		exit 1
	fi
	echo "$action"
}

# Watch the system journal for limine-snapper messages and send desktop notifications for new or important events.
watch_limine_snapper_journal() {
	local line message action now
	local last_notify_time=0
	local pause_time=5

	while IFS= read -r line; do
		# Only process lines containing "limine-snapper"
		[[ "$line" != *limine-snapper* ]] && continue

		# Extract message after the first colon
		message="${line#*: }"

		now=$(date +%s)

		# Pause notifications briefly after a notification was shown
		if ((now - last_notify_time < pause_time)); then
			continue
		fi

		# Reload config if changed
		load_config

		[[ "${ENABLE_NOTIFICATION}" != yes ]] && {
			continue
		}

		# Notify user
		action="$(notify_user "$message")"

		case "$action" in
		closeAction | default) ;;
		disableAction)
			break
			;;
		esac

		# Store last notification state
		last_notify_time=$(date +%s)

	done < <(journalctl --output=short-iso -b -p "$LOG_LEVEL" -n0 -f)
}

# Main logic
if [[ "$EUID" -eq 0 ]]; then
	echo -e "\033[91m$SCRIPT_NAME does not run as root.\033[0m" >&2
	exit 1
fi

if ! command -v journalctl &>/dev/null; then
	echo -e "\033[91mjournalctl is not installed.\033[0m" >&2
	exit 1
fi

load_config
watch_limine_snapper_journal
