#!/usr/bin/bash

CONFIG_FILE=""

function show_version() {
	echo "1.6.0"
}

function show_help() {
	echo "Usage: $0 [-h|--help] [-c|--config FILE] [-v|--version]"
	echo "  -h, --help         Display this help message"
	echo "  -v, --version      Display the version"
	echo "  -c, --config FILE  Use specified configuration file"
	echo "                     (default: ~/.config/journalctl-desktop-notification.conf or ~/.config/journalctl-desktop-notification/local.conf or /etc/journalctl-desktop-notification.conf)"
}

# Parse command-line arguments
while [[ $# -gt 0 ]]; do
	case "$1" in
	-v | --version)
		show_version
		exit 0
		;;
	-h | --help)
		show_help
		exit 0
		;;
	-c | --config)
		if [[ -n "$2" ]]; then
			CONFIG_FILE="$2"
			shift
		else
			echo "$0: option requires an argument -- $1" >&2
			exit 1
		fi
		;;
	*)
		echo "$0: unrecognized option -- $1" >&2
		echo "Try '$0 --help' for more information." >&2
		exit 1
		;;
	esac
	shift
done

# Determine configuration file to use
find_config_file() {
	for path in \
		"$CONFIG_FILE" \
		"$HOME/.config/journalctl-desktop-notification.conf" \
		"$HOME/.config/journalctl-desktop-notification/local.conf" \
		"/etc/journalctl-desktop-notification.conf"; do
		[[ -n "$path" && -f "$path" ]] && {
			echo "$path"
			return 0
		}
	done

	echo "Error: No valid configuration file found." >&2
	return 1
}

CONFIG_FILE="$(find_config_file)" || exit 1
echo "Using configuration file: $CONFIG_FILE"
SSH_ACCESS=""

# Load configuration
load_config() {
	# shellcheck disable=SC1090
	source "$CONFIG_FILE"
	LOG_LEVEL="${LOG_LEVEL:-3}"
	MESSAGE_TIMEOUT="${MESSAGE_TIMEOUT:-0}"
	TITLE="${DESCRIPTION:-"Please check journalctl!"}"

	REMOTE_HOST=$(echo "$REMOTE_HOST" | tr -d ' ')
	if [[ -n "$REMOTE_HOST" ]]; then
		SSH_ACCESS="ssh $REMOTE_HOST"
		TITLE="${DESCRIPTION:-"journalctl from [$REMOTE_HOST]"}"
		#echo "$REMOTE_HOST"
	fi

	SSH_ACCESS_TTY=""
	if [[ -n "$SSH_ACCESS" ]]; then
		SSH_ACCESS_TTY="$SSH_ACCESS -t"
	fi
}

# Get timestamp from the latest log entry
get_timestamp_from_log() {
	if [[ -n "$ERROR_FILTER" ]]; then
		timestamp=$($SSH_ACCESS journalctl --output=short-unix -p "$LOG_LEVEL" -b -n 1 | grep -m1 '' | grep -Ev "$ERROR_FILTER" | cut -d ' ' -f 1)
	else
		timestamp=$($SSH_ACCESS journalctl --output=short-unix -p "$LOG_LEVEL" -b -n 1 | grep -m1 '' | cut -d ' ' -f 1)
	fi

	[[ $timestamp == "--" ]] && timestamp=""
	#echo "Test: $timestamp"
}

# 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
	elif command -v kitty &>/dev/null; then
		echo kitty
	elif command -v xterm &>/dev/null; then
		echo xterm -e
	else
		return 1
	fi
}

# Notify using dunstify or notify-send
notify_user() {
	local action
	if command -v dunstify &>/dev/null; then
		action=$(dunstify -u "critical" --appname="System Notice" --icon="$ERROR_ICON" --action="default,Reply" --action="openAction,Open" --action="disableAction,Disable" --action="closeAction,Close" "$TITLE" "$MESSAGE" -t "$MESSAGE_TIMEOUT")
	elif command -v notify-send &>/dev/null; then
		action=$(notify-send -u "critical" --app-name="System Notice" --icon="$ERROR_ICON" --action="default=Reply" --action="openAction=Open" --action="disableAction=Disable" --action="closeAction=Close" "$TITLE" "$MESSAGE" -t "$MESSAGE_TIMEOUT")
	else
		echo -e "\033[91m libnotify or dunst is not installed.\033[0m"
		exit 1
	fi
	echo "$action"
}

load_config
sleep 3

get_timestamp_from_log
OLD_TIMESTAMP_LINE=$timestamp

TIME_INTERVAL="${TIME_INTERVAL:-2}"

# Main loop
while sleep "$TIME_INTERVAL"; do

	load_config
	get_timestamp_from_log
	TIMESTAMP_LINE=$timestamp

	#echo "Test: $TIMESTAMP_LINE vs $OLD_TIMESTAMP_LINE"

	if [ -n "$TIMESTAMP_LINE" ] && [ "$TIMESTAMP_LINE" != "$OLD_TIMESTAMP_LINE" ]; then
		MESSAGE=$($SSH_ACCESS journalctl --output=cat -p "$LOG_LEVEL" -b -n 1)
		ACTION=$(notify_user)

		case "$ACTION" in
		"disableAction")
			echo "Disabled"
			break
			;;
		"closeAction")
			echo "Closed"
			;;
		"openAction" | "default")
			terminal_cmd=$(get_terminal_command)
			if [[ -n $terminal_cmd ]]; then
				if [[ $terminal_cmd == gnome-terminal* ]] || [[ $terminal_cmd == xfce4-terminal* ]] || [[ $terminal_cmd == mate-terminal* ]]; then
					# Note: gnome-terminal, xfce4-terminal and mate-terminal, which are based on GTK, require quoted string.
					$terminal_cmd "${SSH_ACCESS_TTY} journalctl --no-page -p ${LOG_LEVEL} -b -f"
				else
					# Note: Do not use quoted strings, as some terminals (e.g., foot, alacritty, wezterm, kitty) fail to parse them correctly.
					$terminal_cmd ${SSH_ACCESS_TTY} journalctl --no-page -p ${LOG_LEVEL} -b -f
				fi
			else
				echo -e "\033[1;31m No suitable terminal found.\033[0m"
			fi
			;;
		esac

		get_timestamp_from_log
		OLD_TIMESTAMP_LINE=$timestamp
	fi
done
