#!/bin/sh

autorepo_build_init()
{
    exit_status=0
    branch=$AUTOREPO_BRANCH
    logdir=$AUTOREPO_HOME/logs$hashernumber
}

get_remote_apt_conf()
{
    local target task conffile
    target=$1
    task=$2
    [ -n "$task" ] && task=build
    aptconfbuild=
    for conffile in \
    "$AUTOREPO_LOCAL_APT_DIR/$task.conf.$branch.$target" \
    "$AUTOREPO_LOCAL_APT_DIR/$task.conf.$target" \
    "$AUTOREPO_LOCAL_APT_DIR/build.conf.$branch.$target" \
    "$AUTOREPO_LOCAL_APT_DIR/build.conf.$target" \
    "$AUTOREPO_GLOBAL_APT_DIR/apt.conf.$branch.$target" \
    "$AUTOREPO_LOCAL_APT_DIR/apt.conf.$target" \
	; do
	if [ -e "$conffile" ]; then
	    aptconfbuild="$conffile"
	    return
	fi
    done
    
    echo "get_remote_apt_conf: failed to find apt.conf for $task . $target in $AUTOREPO_LOCAL_APT_DIR:$AUTOREPO_GLOBAL_APT_DIR"
    exit 1
}

set_hasher_dir()
{
    local arch
    arch=$1
    current_hasherdir="$AUTOREPO_HASHER_PREFIX$hashernumber.$arch"
}

arch_build()
{
    local arch
    arch=$1
    shift;
    target=$arch
    aptconfbuild=
    get_remote_apt_conf $target build
    set_hasher_dir "$arch"
    mkdir -p "$current_hasherdir"
    echo $arch hsh "$current_hasherdir" ${hashernumber:+--number $hashernumber} $AUTOREPO_HASHERARGS $AUTOREPO_HASHER_BUILD_ARGS --target=$arch --apt-config=$aptconfbuild "$@"
    $arch hsh "$current_hasherdir" ${hashernumber:+--number $hashernumber} $AUTOREPO_HASHERARGS $AUTOREPO_HASHER_BUILD_ARGS --target=$arch --apt-config=$aptconfbuild "$@" >"$logdir"/hsh.log.$arch 2>&1
    if [ "$?" -gt 0 ]; then
	if egrep "^error: Architecture is (not in|ex)cluded: $arch" "$logdir"/hsh.log.$arch >/dev/null; then
	    touch "$logdir"/exclude.$arch
	else
	    exit_status=3
	fi
    fi
}

arch_cleanup_chroot()
{
    local arch
    arch=$1
    shift;
    set_hasher_dir "$arch"
    [ -d "$current_hasherdir/chroot" ] && hsh-rmchroot ${hashernumber:+--number $hashernumber} "$current_hasherdir"
}

cleanup_chroot()
{
    for arch in $GB_ARCH; do
	arch_cleanup_chroot $arch
    done
}

arch_autorepo_calculate_unmets()
{
    local target difffile
    target=$1
    difffile=$2

    tmp=$TMPDIR/autorepo_calculate_unmets$hashernumber
    aptconflocal=$tmp/apt.conf.$target
    srclistlocal=$tmp/sources.list.$target
    aptconfremote="$AUTOREPO_LOCAL_APT_DIR/apt.conf.$target"
    srclistremote="$AUTOREPO_LOCAL_APT_DIR/sources.list.$target"
    WORKDIR1=$tmp/WD1
    WORKDIR2=$tmp/WD2

cleanup_tmpdir()
    {
	# moved to a subdir
	#rm -f $tmp/unmets.{old,new} $aptconflocal $srclistlocal
	#rm -rf $WORKDIR1 $WORKDIR2
	rm -rf $tmp
    }
    
    cleanup_tmpdir
    mkdir -p $WORKDIR1 $WORKDIR2

    # use APT::Cache-Limit from apt.conf
    sed -e '/^Dir::Etc::sourcelist/d' $aptconfremote > $aptconflocal
    cat >> $aptconflocal <<EOF
Dir::Etc::sourcelist "$srclistlocal";
EOF
    cp $srclistremote $srclistlocal
    set_hasher_dir "$target"
    echo "rpm-dir file:$current_hasherdir/repo ${target} hasher" >> $srclistlocal

    mkaptbox --apt-config=$aptconflocal $WORKDIR2
    $WORKDIR2/aptbox/apt-cache unmet > $tmp/unmets.new
    if [ -s $tmp/unmets.new ]; then
	mkaptbox --apt-config=$aptconfremote $WORKDIR1
	$WORKDIR1/aptbox/apt-cache unmet > $tmp/unmets.old
	diff -U0 $tmp/unmets.{old,new} > $difffile
	if ! egrep -v '^(\+\+\+|@@|-)' $difffile; then
	    # unmets are purely removed, not added
	    rm -f $difffile
	    touch $difffile
	fi
    else
	rm -f $difffile
	touch $difffile
    fi
    cleanup_tmpdir
}

arch_autorepo_install_test()
{
    local exit_status arch rpm logfile initroot_stamp initroot_created
    exit_status=0
    arch="$1"
    rpm="$2"
    logfile="$3"
    initroot_stamp="$4"
    shift; shift; shift; shift;
    target=$arch
    aptconfbuild=
    get_remote_apt_conf $target apt
    initroot_created=
    set_hasher_dir "$arch"
    mkdir -p "$current_hasherdir"
    if ! [ -f "$initroot_stamp" ]; then
	# trying to reuse existing chroot; not doing --initroot-only if already done
	echo $arch hsh --target=$arch --with-stuff ${hashernumber:+--number $hashernumber} "$current_hasherdir" $AUTOREPO_HASHERARGS --apt-config=$aptconfbuild --initroot-only
	$arch hsh --target=$arch --with-stuff ${hashernumber:+--number $hashernumber} "$current_hasherdir" $AUTOREPO_HASHERARGS --apt-config=$aptconfbuild --initroot-only > "$logfile" 2>&1
	touch "$initroot_stamp"
	initroot_created=yes
    fi
    echo $arch hsh-install $AUTOREPO_HASHERARGS "$current_hasherdir" "$rpm"
    $arch hsh-install $AUTOREPO_HASHERARGS "$current_hasherdir" "$rpm" >> "$logfile" 2>&1
    if [ "$?" -gt 0 ]; then
	if [ -n "$initroot_created" ]; then
	    exit_status=5
	else
	    # reinitializing chroot as installation failed in shared chroot
	    echo $arch hsh --target=$arch --with-stuff ${hashernumber:+--number $hashernumber} "$current_hasherdir" $AUTOREPO_HASHERARGS $AUTOREPO_HSH_ARGS --apt-config=$aptconfbuild --initroot-only
	    $arch hsh --target=$arch --with-stuff ${hashernumber:+--number $hashernumber} "$current_hasherdir" $AUTOREPO_HASHERARGS $AUTOREPO_HSH_ARGS --apt-config=$aptconfbuild --initroot-only > "$logfile" 2>&1
	    echo $arch hsh-install $AUTOREPO_HASHERARGS $AUTOREPO_HSH_INSTALL_ARGS "$current_hasherdir" "$rpm"
	    $arch hsh-install $AUTOREPO_HASHERARGS $AUTOREPO_HSH_INSTALL_ARGS "$current_hasherdir" "$rpm" >> "$logfile" 2>&1
	    if [ "$?" -gt 0 ]; then
		exit_status=5
	    fi
	fi
    fi
    return $exit_status
}

autorepo_build()
{
    for arch in $GB_ARCH; do
	arch_build $arch "$@"
	if [ "$rapid_drop_mode" -gt 0 ] && [ "$exit_status" -gt 0 ]; then
	    echo "rebuild failed."
	    cleanup_chroot
	    exit $exit_status
	fi
    done
    
    if [ "$exit_status" -gt 0 ]; then
	echo "rebuild failed."
	cleanup_chroot
	exit $exit_status
    fi

    touch "$logdir"/build.success
}

autorepo_calculate_unmets()
{
    for arch in $GB_ARCH; do
	mkdir -p "$logdir"
	rm -f "$logdir"/unmets.diff.$arch
	[ -e "$logdir"/exclude.$arch ] || arch_autorepo_calculate_unmets $arch "$logdir"/unmets.diff.$arch
	[ -s "$logdir"/unmets.diff.$arch ] && exit_status=4
    done

    if [ "$exit_status" -gt 0 ]; then
	echo "unmets test failed."
	cleanup_chroot
	exit $exit_status
    fi

    touch "$logdir"/unmets.success
}

autorepo_install_test()
{
    for arch in $GB_ARCH; do
	initroot_stamp="$logdir"/initroot-${arch}.done
	rm -f "$initroot_stamp"
	if ! [ -e "$logdir"/exclude.$arch ]; then
	    set_hasher_dir "$arch"
	    for rpm in "$current_hasherdir"/repo/$arch/RPMS.hasher/*.rpm; do
		if [ -e "$rpm" ]; then # -e because w/o nullglob
		    logfile="$logdir"/`basename $rpm`-${arch}-install.log
		    if arch_autorepo_install_test $arch "$rpm" "$logfile" "$initroot_stamp"; then
			rm -f "$logfile"
		    else
			echo "$rpm: install test failed"
			exit_status=5
		    fi
		fi
	    done
	fi
    done

    if [ "$exit_status" -gt 0 ]; then
	echo "install test failed."
	cleanup_chroot
	exit $exit_status
    fi

    touch "$logdir"/install.success
}


