#!/usr/bin/env bash

readonly SCRIPT_NAME="limine-entry-tool"
readonly LIMINE_LOCK_FILE="/tmp/limine-global.lock"
export HOOK_CALLER="${HOOK_CALLER:-$SCRIPT_NAME}"
export HOOK_CMDLINE="$*"

ENABLE_MUTEX=true
ENABLE_HOOKS=true
ARGS=()

for arg in "$@"; do
	case "$arg" in
	--no-mutex)
		ENABLE_MUTEX=false
		;;
	--mutex)
		ENABLE_MUTEX=true
		;;
	--no-hooks)
		ENABLE_HOOKS=false
		;;
	--hooks)
		ENABLE_HOOKS=true
		;;
	--help | --version | --get-cmdline)
		ENABLE_MUTEX=false
		ENABLE_HOOKS=false
		ARGS+=("$arg")
		;;
	*)
		ARGS+=("$arg")
		;;
	esac
done

_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

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

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

if [[ $EUID -ne 0 ]]; then
	error_msg "${SCRIPT_NAME} must be run with root privileges."
	exit 1
fi

run_boot_hooks() {
	local dir="$1"
	local hook rc=0
	for hook in /etc/boot/hooks/"$dir".d/*; do
		[[ -f $hook && -x $hook && $hook != *.disabled ]] || continue
		rc=0
		"$hook" || rc=$?
		((rc == 0)) && continue
		if ((rc >= 100)); then
			error_msg "$dir hook failed (exit code $rc): $hook"
			logger -p err -t "${SCRIPT_NAME}" "$dir hook failed (exit code $rc): $hook"
			return "$rc"
		else
			warning_msg "$dir hook failed (exit code $rc): $hook"
			logger -p warning -t "${SCRIPT_NAME}" "$dir hook failed (exit code $rc): $hook"
		fi
	done
	return "$rc"
}

mutex_lock() {
	local name=$1
	exec 200>${LIMINE_LOCK_FILE} || {
		rm -f ${LIMINE_LOCK_FILE}
		exec 200>${LIMINE_LOCK_FILE}
	}
	flock --timeout=10 200 || {
		warning_msg "Mutex lock timeout on ${name}."
		return 1
	}
}

mutex_unlock() {
	flock --unlock 200
}

if $ENABLE_MUTEX; then
	mutex_lock "${SCRIPT_NAME}"
	trap mutex_unlock EXIT
fi

if $ENABLE_HOOKS; then
	rc=0
	run_boot_hooks pre || rc=$?
	if ((rc >= 100)); then
		exit "$rc"
	fi
fi

/usr/lib/limine/limine-entry-tool "${ARGS[@]}"
exit_code="$?"

if $ENABLE_HOOKS; then
	run_boot_hooks post || exit
fi

exit "$exit_code"
