#!/bin/bash

if [ -z "${__uevent_sh_functions-}" ]; then
__uevent_sh_functions=1

. shell-error

uevent_rootpath="${uevent_rootpath-}"
uevent_basepath="${uevent_basepath:-.initrd}"

uevent_confdb="$uevent_rootpath/$uevent_basepath/uevent/confdb"

debugdir="$uevent_rootpath/$uevent_basepath/uevent/debug"
filterdir="$uevent_rootpath/$uevent_basepath/uevent/queues"
timerdir="$uevent_rootpath/$uevent_basepath/uevent/timers"
ueventdir="$uevent_rootpath/$uevent_basepath/uevent/events"

# backward compatibility
eventdir="$uevent_rootpath/$uevent_basepath/uevent/events/udev"

handlerdir="$uevent_rootpath/lib/uevent/handlers"
timestamp_bin="${TIMESTAMP:-/sbin/timestamp}"

make_event() {
	mktemp "$filterdir/${1:-udev}/.tmp/.XXXXXXXXX"
}

make_timer_event() {
	local queue="${1:-udev}"

	mkdir -p -- "$filterdir/$queue/.tmp" "$timerdir/$queue/.tmp"
	mktemp "$timerdir/$queue/.tmp/.XXXXXXXXX"
}

publish_event() {
	mv -f -- "$2" "${2%/.tmp/*}/$1"
}

release_event() {
	local num dummy
	num=$("$timestamp_bin" boottime simple)
	publish_event "$1.${num:-0.0}${2##*/}" "$2"
}

release_event_at() {
	local queue="$1" due="$2" name="$3" event="$4"
	local num

	due="${due%.*}"
	mkdir -p -- "$filterdir/$queue/.tmp" "$timerdir/$queue/.tmp"
	num=$("$timestamp_bin" boottime simple)
	publish_event "$due.$name.${num:-0.0}${event##*/}" "$event"
}

release_event_after() {
	local queue="$1" delay="$2" name="$3" event="$4"
	local now due

	now=$("$timestamp_bin" boottime raw)
	now="${now%.*}"
	due=$(( now + delay ))
	release_event_at "$queue" "$due" "$name" "$event"
}

queue_event_after() {
	local queue="$1" delay="$2" type="$3" name="$4"
	local event

	shift 4

	event="$(make_timer_event "$queue")"
	{
		printf 'TYPE=%s\n' "$type"
		printf 'NAME=%s\n' "$name"
		printf 'QUEUE=%s\n' "$queue"
		printf 'DELAY=%s\n' "$delay"
		printf '%s\n' "$@"
	} > "$event"

	release_event_after "$queue" "$delay" "$type.$name" "$event"
}

queue_retry_after() {
	queue_event_after "$1" "$2" retry "$3" "${@:4}"
}

queue_timeout_after() {
	queue_event_after "$1" "$2" timeout "$3" "${@:4}"
}

queue_cancel_events() {
	local queue="$1" type="$2" name="$3"

	find "$timerdir/$queue" -maxdepth 1 -type f -name "*.$type.$name.*" -delete 2>/dev/null ||:
}

queue_cancel_retries() {
	queue_cancel_events "$1" retry "$2"
}

queue_cancel_timeouts() {
	queue_cancel_events "$1" timeout "$2"
}

done_event() {
	rm -f -- "$1"
	message "finish event: $1" ||:
}

fi
