#!/bin/sh

### global variables

profiledir="/var/lib/install3"

groupsdir="$profiledir/groups"
listsdir="$profiledir/lists"
testsdir="$profiledir/tests"

pipedir="/var/run/alterator-pkg/"
errpipe="$pipedir/stderr.fifo"
inpipe="$pipedir/stdin.fifo"

alterator_api_version=1

pipe_pid=
templist=

. alterator-sh-functions

### pipe handlers

exit_handler()
{
    local rc=$?
    trap - EXIT
	
    rm -f "$templist"
    stop_pipe
    exit $rc
}

stdin_handler()
{
    while :; do
        [  -e "$inpipe" ] || break
    	    while read n; do
	        if [ "$n" = "q" ]; then
	    	    rm -f "$inpipe"
		    break 2
		fi
		echo "$n"
	    done < "$inpipe"
    done
}

message_quote()
{
    echo "$1"|string_quote
}

stderr_handler()
{
    while read -r n; do
	printf >&2 '%s\n' "$n"
	alterator-mailbox-send "error \"$(message_quote "$n")\""
    done <"$errpipe"
}

stdout_handler()
{
    while read -r n;do
	[ -z "${DURING_INSTALL-}" ] ||
		printf >&2 '%s\n' "$n"
	alterator-mailbox-send "message \"$(message_quote "$n")\""
    done
    write_pipe "q"
}


### main pipe operations

make_manifest()
{
    [ "$#" -gt 0 ] || return

    templist="$(mktemp -t pkg-install.XXXXXX)"

	cd "$listsdir"
	    cat "$@"|
		sed -r \
		    -e '/^[[:space:]]*$/ d'\
		    -e '/^[[:space:]]*#/ d' >"$templist"
	cd - >/dev/null

    echo "$templist"
}

#note first install rpm to have correct package install order (setup and filesystem should be first packages)
make_apt()
{
	local rc=0
	echo "pkg-install:start"
	local base_tmpfile="$(make_manifest .base)"
	local rest_tmpfile="$(make_manifest $in_lists)"

	echo "base_tmpfile=$base_tmpfile" >&2
	echo "rest_tmpfile=$rest_tmpfile" >&2

	if [ -s "$base_tmpfile" -o -s "$rest_tmpfile" ]; then
	    echo "pkg-install:stage-index"
	    apt-get update

	    echo "pkg-install:stage-rpm"
	    apt-get -y --simple-output install rpm

	    echo "pkg-install:stage-install-base"
	    if [ -s "$base_tmpfile" ]; then
		if test_bool "$in_auto" ]; then
		    apt-get -y --simple-output install --manifest "$base_tmpfile" || rc=$?
		else
		    stderr_handler &
		    apt-get -y --simple-output install --manifest "$base_tmpfile" 2>"$errpipe" || rc=$?
		fi
	    fi

	    echo "pkg-install:stage-install-rest"
	    if [ "$rc" = "0" -a -s "$rest_tmpfile" ]; then
		if test_bool "$in_auto"; then
		    apt-get -y --simple-output install --manifest "$rest_tmpfile" || rc=$?
		else
		    stderr_handler &
		    apt-get -y --simple-output install --manifest "$rest_tmpfile" 2>"$errpipe" || rc=$?
		fi
	    fi
	fi
	rm -f -- "$base_tmpfile" "$rest_tmpfile"
	echo "pkg-install:finish:$rc"
}

make_pipe()
{
    mkdir -p "$pipedir"
    [ -p "$errpipe" ] || (rm -rf "$errpipe"; mkfifo -m600 "$errpipe")
    [ -p "$inpipe" ] || (rm -rf "$inpipe"; mkfifo -m600 "$inpipe")

    stdin_handler|make_apt|stdout_handler
}

write_pipe()
{
    if [ -n "$pipe_pid" ] && kill -0 "$pipe_pid" ;then
	[ ! -p "$inpipe" ] || echo "$in_message" >"$inpipe"
    fi
}

stop_pipe()
{
    write_pipe "q"
    killall -9 apt-get >/dev/null 2>/dev/null ||:
    rm -f "$errpipe" "$inpipe"
}

start_pipe()
{
    run-parts /usr/lib/alterator/hooks/pkg-preinstall.d
    stop_pipe
    make_pipe&
    pipe_pid=$!
}

### initial actions

export LANG=C
trap exit_handler EXIT HUP INT QUIT TERM

on_message()
{
	case "$in_action" in
		write)
			case "$in__objects" in
			    /)
				if test_bool "$in_auto"; then
					make_apt < /dev/null &> /tmp/pkg-install.log
				else
					start_pipe
				fi
				;;
			    notify)
				write_pipe "$in_message"
				;;
			esac
			;;
	esac
}

message_loop
