#!/bin/bash -efu

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

. /.initrd/initenv
. uevent-sh-functions

handlerdir="/lib/pipeline"
mntdir="/dev/pipeline"

check_parameter()
{
	local v
	eval "v=\"\${$1-}\""
	[ -n "$v" ] ||
		fatal "Parameter '$1' required"
}

get_parameter()
{
	eval "printf '%s' \"\${${1}$callnum-}\""
}

resolve_target()
{
	local target="$1"
	case "${target%%/*}" in
		'')
			;;
		pipe[0-9]|pipe[0-9][0-9]|pipe[0-9][0-9][0-9])
			target="$mntdir/dst/$target"
			;;
		*)
			if [ -z "${prevdir-}" ]; then
				message "no previous stop to use"
				return
			fi
			target="$prevdir/${target#/}"
			;;
	esac
	printf '%s' "$target"
}

run()
{
	[ -z "${DEBUG-}" ] || message "[$callnum] RUN: $*"
	"$@"
}

pipe_name()
{

	local -a arr

	IFS="," read -r -a arr <<<"$PIPELINE"

	if [ "$1" -ge "${#arr[@]}" ]; then
		eval "name=\"\""
		return 0
	fi

	local n="$1"

	set -- "${arr[@]}"
	shift $n

	eval "name=\"\$1\""
}

pipe_callnum()
{
	local -a arr

	IFS="," read -r -a arr <<<"$PIPELINE"

	if [ "$1" -ge "${#arr[@]}" ]; then
		eval "callnum=\"\""
		return 0
	fi

	local n="$1"

	set -- "${arr[@]}"
	shift $n

	local i num=0
	for (( i=0; $i < $n; i+=1 )); do
		[ "$1" != "${arr[$i]}" ] || num=$(( $num + 1 ))
	done

	eval "callnum=\"\$num\""
}

pipe_init()
{
	local event
	event="$(make_event pipeline)"
	release_event "pipeline.init" "$event"
}

pipe_event()
{
	local event

	message "create event: $1${2:+ move #$2} -> step #$3"

	event="$(make_event pipeline)"
	printf > "$event" '%s\n' \
		"prevnum=$2" \
		"pipenum=$3"

	release_event "$1" "$event"
}

pipe_failed()
{
	[ -n "${PIPE_RETRY:-}" ] ||
		return 0

	local failed fn

	failed=0
	fn="/.initrd/pipeline/step-failed/$callnum"

	[ ! -f "$fn" ] || read -r failed < "$fn"
	failed="$(( $failed + 1 ))"

	echo "$failed" > "$fn"

	[ "$failed" -le "${PIPE_RETRY:-}" ]
}

PIPE_RETCODE_STOP=2
pipe_fatal()
{
	message "$*"
	exit $PIPE_RETCODE_STOP
}

in_comma_list()
{
	local var arg list

	var="$1"; shift

	list=()
	readarray -t -d, list < <(printf '%s' "$1")

	for arg in "${list[@]}"; do
		[ "$var" != "$arg" ] || return 0
	done
	return 1
}

pipe_gpg_verify()
{
	local stepname signfile datafile gpg err

	stepname="$1"; shift
	signfile="$1"; shift
	datafile="$1"; shift

	in_comma_list "$stepname" "${PIPE_VERIFY_SIGN-}" ||
		return 0

	gpg="$(type -P gpg)" ||
		pipe_fatal "gpg utility detected."

	[ -f "$signfile" ] ||
		pipe_fatal "unable to verify the signature because the signature file could not be found: $signfile"

	err="$("$gpg" --verify --homedir /etc/initrd/gnupg "$signfile" "$datafile")" ||
		pipe_fatal "$err"
}

fi # __pipeline_sh_functions
