#!/usr/bin/env bash

readonly SCRIPT_NAME="limine-snapper-watcher"
readonly WATCH_DIR="/.snapshots"
readonly BASE_CONFIG="/etc/limine-snapper-sync.conf"
readonly DEFAULT_CONFIG="/etc/default/limine"
readonly TMP_CONFIG="/tmp/limine-snapper-sync.conf"
readonly SYNC_CMD=(limine-snapper-sync --no-force-save)

_color_reset=""
_color_yellow=""
_color_red=""
colors="$(tput colors 2>/dev/null || echo 0)"
if ((colors >= 8)); then
	_color_reset="\033[0m"
	_color_yellow="\033[1;33m"
	_color_red="\033[1;31m"
fi

info_msg() {
	echo "$1"
}

warning_msg() {
	echo -e "${_color_yellow}WARNING: $1${_color_reset} ${2:-}" >&2
}

error_msg() {
	echo -e "${_color_red}ERROR: $1${_color_reset} ${2:-}" >&2
}

### Check if the script is being run with root privileges
require_root() {
	if ((EUID != 0)); then
		error_msg "${SCRIPT_NAME} must be run with root privileges."
		exit 1
	fi
}

### Check if you are not in Btrfs.
require_btrfs_root() {
	local fstype
	read -r fstype < <(findmnt --mountpoint / -no FSTYPE)
	if [[ "$fstype" != "btrfs" ]]; then
		warning_msg "Root filesystem is not Btrfs. ${SCRIPT_NAME} stopped."
		exit 0
	fi
}

is_btrfs_ro() {
	[[ $(btrfs property get / ro) == *true ]]
}

### Check if you are in snapshot
is_snapshot() {
	cmdline=$(</proc/cmdline)
	if [[ $cmdline =~ rootflags.*subvol=.*?/([0-9]+)/snapshot ]]; then
		return 0
	else
		return 1
	fi
}

copy_config_if_needed() {
	if is_btrfs_ro && is_snapshot && [[ ! -f "${TMP_CONFIG}" ]]; then
		if [[ -f "${DEFAULT_CONFIG}" ]]; then
			cp "${DEFAULT_CONFIG}" "${TMP_CONFIG}"
		elif [[ -f "${BASE_CONFIG}" ]]; then
			cp "${BASE_CONFIG}" "${TMP_CONFIG}"
		fi
	fi
}

### Remove pacman lock after restore for Arch Linux & Arch based distros
remove_pacman_lock() {
	if [[ -f /var/lib/pacman/db.lck ]]; then
		if ! pgrep -x pacman &>/dev/null; then
			rm /var/lib/pacman/db.lck
		fi
	fi
}

### Main logic
require_root
require_btrfs_root
copy_config_if_needed

if is_btrfs_ro; then
	warning_msg "You are in the read-only Btrfs. ${SCRIPT_NAME} stopped."
	exit 0
fi

if is_snapshot; then
	warning_msg "You are booted from the snapshot. ${SCRIPT_NAME} stopped."
	exit 0
fi

remove_pacman_lock

### Initial sync
if [ ! -d "$WATCH_DIR" ]; then
	echo "Directory $WATCH_DIR does not exist. limine-snapper-sync is triggered to initialize a snapper config for $WATCH_DIR."
	"${SYNC_CMD[@]}"
fi

if ! command -v inotifywait &>/dev/null; then
	warning_msg "inotifywait is not installed."
	exit 0
fi

### Monitoring the directory for creation or deletion events.
inotifywait -q -m -e create -e delete --format '%e|%f' "${WATCH_DIR}" | while IFS='|' read -r event snapID; do
	info_msg "[EVENT] $event -> $snapID"
	if [[ -e /run/limine-snapper-cleanup.lock ]]; then
		info_msg "[SKIP] Cleanup lock is active, skipping sync for snapshot ID: $snapID"
	else
		"${SYNC_CMD[@]}" &
	fi
done
