#!/bin/bash -efu

. altboot-sh-functions

# altboot_checksum=<HASH> -or-
# altboot_checksum=[<hashprog>]:<HASH> -or-
# altboot_checksum=[<hashprog>]:<HASH>:<filename>
# Example: md5sum:01234567890123456789:/live

check_parameter ALTBOOT_CHECKSUM

check=
hashprog=
filename=
fullpath=
datasize=0


check_prevstep_results()
{
	enter "check_prevstep_results"

	[ -n "$prevdir" ] ||
		return 1

	if [ "${filename:0:1}" = "/" ]; then
		fullpath="${prevdir}${filename}"
		mountpoint -q -- "$prevdir" && [ -r "$fullpath" ] ||
			return 1
		datasize="$(run stat -L -c%s -- "$fullpath" ||:)"
		[ -n "$datasize" ] ||
			return 1
	elif [ -r "$prevdir/DEVNAME" ]; then
		[ -r "$prevdir/FILESIZE" ] &&
		read -r filename <"$prevdir/DEVNAME" &&
		read -r datasize <"$prevdir/FILESIZE" &&
		[ -b "$filename" ] && [ -n "$datasize" ] ||
			return 1
		fullpath="$filename"
	else
		[ -b "$prevdir/dev" ] &&
		[ -r "$prevdir/FILESIZE" ] &&
		read -r datasize <"$prevdir/FILESIZE" &&
		[ -n "$datasize" ] ||
			return 1
		filename="$prevdir/dev"
		fullpath="$filename"
	fi

	leave "check_prevstep_results"
}


# Entry point
[ -z "$ALTBOOT_OLDROOT" ] ||
	launch_step_once
get_bootarg CHECKSUM
debug "$PROG started ($CHECKSUM)"

if [ "$CHECKSUM" != "${CHECKSUM#*:}" ]; then
	hashprog="${CHECKSUM%%:*}"
	CHECKSUM="${CHECKSUM#*:}"
	if [ "$CHECKSUM" != "${CHECKSUM#*:}" ]; then
		filename="${CHECKSUM#*:}"
		CHECKSUM="${CHECKSUM%%:*}"
	fi
fi

IM_start_output gauge

hashprog="${hashprog:-sha256sum}"
command -v "$hashprog" >/dev/null ||
	IM_fatal "hash program not found: $hashprog"
[ -n "$CHECKSUM" ] ||
	IM_fatal "hash summa not specified"
check_prevstep_results ||
	fatal "no previous step results to use with $PROG"
[ "$datasize" -gt 0 ] 2>/dev/null ||
	IM_fatal "invalid data size: $datasize"

debug "hash summa: $CHECKSUM"
debug "hash data size: $datasize"
debug "hash check program: $hashprog"

message "calculating image checksum for '$filename'..."

:> /.initrd/rootdelay/addtime
rootdelay_pause

{ head -c "$datasize" -- "$fullpath" |
  pv -n -i 0.5 -s $datasize |
  "$hashprog" |
  cut -f1 -d' ' >"$datadir/CHECKSUM"
} 2>&1 |IM_gauge "[ Validating image... ]"

[ -r "$datadir/CHECKSUM" ] &&
	read -r check <"$datadir/CHECKSUM" ||
	check="not checked"
rm -f -- "$datadir/CHECKSUM"
debug "calculated hash: $check"

[ "$CHECKSUM" = "$check" ] ||
	IM_fatal "image file checksum mismatch"
message "checksum verified successfully"

# shellcheck disable=SC2119
bypass_results

debug "$PROG finished"
