#!/bin/sh
#
# Sorge dafuer, dass nach einem Boot-Vorgang ein passender Log-Eintrag in
# die Banner-Datei geschrieben wird.
# Vor dem Schreiben des Zeitstempels wird geprueft, ob die aktuelle Systemzeit
# mit der Zeit der konfigurierten Zeitserver grob uebereinstimmt. Falls dies
# nicht der Fall ist, wird der Log-Vorgang verschoben, bis eine maximale
# Wartezeit ueberschritten ist. Anschliessend erfolgt die Ausgabe mit einem
# passenden Text ("no time retrieved").
#
# Falls die maximal zulässige Zeit noch nicht abgelaufen ist, wird eine erneute
# Ausführung via 'schedule_task' veranlasst.

# shellcheck source=opennet/packages/on-core/files/usr/lib/opennet/on-helper.sh
. "${IPKG_INSTROOT:-}/usr/lib/opennet/on-helper.sh"


MAX_UPTIME_SECONDS=360
ACCEPTABLE_TIME_OFFSET=180


get_current_time_offset_milliseconds() {
	local peer_args=
	local peer
	local offsets
	# Die Liste der konfigurierten Zeitserver auslesen und als Argumente fuer ntpd zusammensetzen.
	for peer in $(uci_get_list system.ntp.server); do
		[ -z "$peer" ] || peer_args="$peer_args -p $peer"
	done
	[ -z "$peer_args" ] && return 0
	# Alle konfigurierten Zeitserver abfragen.
	# Wir sind lediglich am "offset"-Wert interessiert.
	# shellcheck disable=SC2086
	offsets=$(timeout -s INT 4 ntpd -w -n -q $peer_args 2>&1 \
		| grep "offset:" \
		| cut -f 4 -d : \
		| cut -f 1 -d " ")
	# Keine Zeitserver erreichbar? Abbruch ...
	[ -z "$offsets" ] && return 0
	# Durchschnitt der Offsets ermitteln.
	echo "$offsets" | awk '
		BEGIN { summe=0; zaehler=1; }
		{ summe+=$1; zaehler+=1; }
		END { print int((summe * 1000) / zaehler) }'
}


# Uptime und Zeitsynchronitaet ermitteln
time_offset=$(get_current_time_offset_milliseconds)
uptime=$(get_uptime_seconds)
# beide Bedingungen voneinander trennen - sonst liefert ash eine Fehlermeldung, falls "time_offset" leer ist
if [ -z "$time_offset" ] || [ "$time_offset" -gt "$ACCEPTABLE_TIME_OFFSET" ]; then
	# bisher fand kein Zeitabgleich statt - wir pruefen, ob die uptime inzwischen abgelaufen ist
	# Ist die maximale Uptime abgelaufen? Falls nicht, dann warten wir auf den naechsten Versuch.
	[ "$uptime" -lt "$MAX_UPTIME_SECONDS" ] && echo "$0" | schedule_task && exit 0
	# Die Zeit ist um - wir schreiben den ungueltigen Zeitstempel.
	timestamp="(no time retrieved)"
else
	# unsere Zeit ist synchronisert - wir koennen das reboot-Log schreiben
	# Ziehe von der aktuellen Zeit die uptime ab
	boot_time=$(($(date +%s) - uptime))
	timestamp=$(date --date "@$boot_time")
fi

# Schreibe den Zeitstempel
add_banner_event "system restart" "$timestamp"
# wir sind fertig
