#!/usr/bin/env bash

# XDG compliant config resolution
readonly CONFIG_FILE="${XDG_CONFIG_HOME:-$HOME/.config}/btrfs-desktop-notification.conf"

# 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_config() {
	local config_loaded=false

	if [[ -f "$CONFIG_FILE" ]]; then
		load_key_value_config "$CONFIG_FILE"
		config_loaded=true
	else
		# Try XDG_CONFIG_DIRS (colon separated, ordered by importance)
		local dirs="${XDG_CONFIG_DIRS:-/etc/xdg}"
		IFS=":" read -ra config_dirs <<<"$dirs"

		for dir in "${config_dirs[@]}"; do
			if [[ -f "$dir/btrfs-desktop-notification.conf" ]]; then
				load_key_value_config "$dir/btrfs-desktop-notification.conf"
				config_loaded=true
				break
			fi
		done
	fi

	# Fallback if still nothing was loaded
	if ! $config_loaded && [[ -f /etc/btrfs-desktop-notification.conf ]]; then
		load_key_value_config /etc/btrfs-desktop-notification.conf
		config_loaded=true
	fi

	# Apply defaults if values are missing
	TITLE="${TITLE:-BTRFS messages detected in dmesg}"
	LOG_LEVEL="${LOG_LEVEL:-4}"
	ERROR_ICON="${ERROR_ICON:-dialog-warning}"
	INFO_ICON="${INFO_ICON:-dialog-warning}"
}

# Define available terminals with proper default arguments
get_terminal_command() {
	if [[ -n "${TERMINAL:-}" ]] && command -v "${TERMINAL}" &>/dev/null; then
		# Set a default TERMINAL_ARG if it's not specified
		case "${TERMINAL}" in
		gnome-terminal)
			echo "${TERMINAL} ${TERMINAL_ARG:--- bash -c}"
			;;
		*)
			echo "${TERMINAL} ${TERMINAL_ARG:--e}"
			;;
		esac
	elif command -v konsole &>/dev/null; then
		echo konsole -e
	elif command -v gnome-terminal &>/dev/null; then
		echo gnome-terminal -- bash -c
	elif command -v xfce4-terminal &>/dev/null; then
		echo xfce4-terminal -e
	elif command -v qterminal &>/dev/null; then
		echo qterminal -e
	elif command -v mate-terminal &>/dev/null; then
		echo mate-terminal -e
	elif command -v kgx &>/dev/null; then
		echo kgx -e
	elif command -v deepin-terminal &>/dev/null; then
		echo deepin-terminal -e
	elif command -v foot &>/dev/null; then
		echo foot -e
	elif command -v kitty &>/dev/null; then
		echo kitty -e
	elif command -v wezterm &>/dev/null; then
		echo wezterm start
	elif command -v alacritty &>/dev/null; then
		echo alacritty -e
	elif command -v ptyxis &>/dev/null; then
		echo ptyxis -e
	elif command -v ghostty &>/dev/null; then
		echo ghostty -e
	elif command -v xterm &>/dev/null; then
		echo xterm -e
	else
		return 1
	fi
}

# Notify if booted into a read-only Btrfs system
notify_readonly_btrfs() {
	[[ "${DETECT_RO_SNAPSHOT:-}" != "yes" ]] && return

	if [[ "$(btrfs property get / ro 2>/dev/null)" == *ro=true* ]]; then
		local msg="System booted into a read-only Btrfs filesystem or snapshot."

		if command -v notify-send &>/dev/null; then
			notify-send -u critical --app-name="Read-Only Btrfs Detected" --icon="$INFO_ICON" "$msg"
		else
			echo -e "\033[91m libnotify is not installed.\033[0m" >&2
			logger -t btrfs-desktop-notification -p err "libnotify is not installed - cannot send read-only Btrfs alert."
		fi
	fi
}

# Notify using notify-send
notify_user() {
	local action="" msg="$1"
	if command -v notify-send &>/dev/null; then
		action=$(notify-send -u "critical" --app-name="Detected BTRFS message!" --icon="$ERROR_ICON" --action="default=Reply" --action="openAction=Open" --action="disableAction=Disable" --action="closeAction=Close" "$TITLE" "$msg")
	else
		echo -e "\033[91m libnotify is not installed.\033[0m" >&2
		logger -t btrfs-desktop-notification -p err "libnotify is not installed."
		exit 1
	fi
	echo "$action"
}

# Get last timestamp from the BTRFS-related kernel log
last_timestamp_from_dmesg() {
	local line
	line=$(journalctl --dmesg --output=short-iso -b -p "$LOG_LEVEL" --grep "BTRFS" -n1)

	# Extract first field as timestamp
	ts="${line%% *}"

	# Accept only valid ISO-8601-like timestamps (YYYY-MM-DDT...)
	if [[ "$ts" == ????-??-??T* ]]; then
		echo "$ts"
	else
		echo ""
	fi
}

# Stream live BTRFS kernel messages and trigger notifications
stream_btrfs_alerts() {
	local last_timestamp timestamp message action
	last_timestamp=""

	journalctl --dmesg --output=short-iso -b -p "$LOG_LEVEL" --grep "BTRFS" -f |
		while read -r line; do
			# Extract timestamp
			timestamp="${line%% *}"

			# Skip if the timestamp is invalid
			[[ "$timestamp" != ????-??-??T* ]] && continue

			# Skip if the timestamp is not newer than the last timestamp of the notification
			[[ "$timestamp" < "$last_timestamp" || "$timestamp" == "$last_timestamp" ]] && continue

			# reload config on change
			load_config

			# Extract the message text from the journal line
			message="${line#* }"
			message="${message#* }"

			# Call notify_user with the message
			action="$(notify_user "$message")"

			case "$action" in
			"disableAction")
				echo "Disabled"
				return
				;;
			"closeAction")
				# do nothing
				;;
			"openAction" | "default")
				# Read terminal command into an array
				read -r -a terminal_cmd <<<"$(get_terminal_command)"

				if [[ ${#terminal_cmd[@]} -eq 0 ]]; then
					echo -e "\033[1;31m No suitable terminal found. Please configure TERMINAL=<terminal app> in '~/.config/btrfs-desktop-notification.conf'\033[0m" >&2
				else
					# Note: GTK terminals require a single quoted command string
					if [[ ${terminal_cmd[0]} == gnome-terminal* || ${terminal_cmd[0]} == xfce4-terminal* || ${terminal_cmd[0]} == mate-terminal* ]]; then
						"${terminal_cmd[@]}" "journalctl --dmesg --no-pager -p ${LOG_LEVEL} -b -f"
					else
						# Other terminals expect raw args
						"${terminal_cmd[@]}" journalctl --dmesg --no-pager -p "${LOG_LEVEL}" -b -f
					fi
				fi
				;;
			esac

			# Update the last timestamp after closing the notification. This is important to prevent repeatedly spamming users.
			last_timestamp="$(last_timestamp_from_dmesg)"
		done
}

# Main logic
load_config
notify_readonly_btrfs
stream_btrfs_alerts
