#!/bin/sh

exit_status=0

. autorepo-config

branch=$AUTOREPO_BRANCH
logdir=$AUTOREPO_HOME/logs
rm -rf $logdir
mkdir -p $logdir

for arch in $GB_ARCH; do
    rm -rf $AUTOREPO_HASHER_PREFIX$arch/repo
done

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
}

arch_build()
{
    local arch
    arch=$1
    shift;
    target=$arch
    aptconfbuild=
    get_remote_apt_conf $target build
    mkdir -p $AUTOREPO_HASHER_PREFIX$arch
    echo $arch hsh $AUTOREPO_HASHER_PREFIX$arch $AUTOREPO_HASHERARGS --target=$arch --apt-config=$aptconfbuild "$@"
    $arch hsh $AUTOREPO_HASHER_PREFIX$arch $AUTOREPO_HASHERARGS --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
}

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

    tmp=$TMPDIR
    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()
    {
	rm -f $tmp/unmets.{old,new} $aptconflocal $srclistlocal
	rm -rf $WORKDIR1 $WORKDIR2
    }
    
    cleanup_tmpdir
    mkdir -p $WORKDIR1 $WORKDIR2

    cat > $aptconflocal <<EOF
Dir::Etc::main "/dev/null";
Dir::Etc::parts "/var/empty";
Dir::Etc::SourceParts "/var/empty";

Dir::Etc::sourcelist "$srclistlocal";

Debug::PkgProblemResolver "true";

// APT::Cache-Limit 100000000;
EOF
    cp $srclistremote $srclistlocal
    echo "rpm-dir file:$AUTOREPO_HASHER_PREFIX$target/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
    else
	rm -f $difffile
	touch $difffile
    fi
    cleanup_tmpdir
}

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=
    mkdir -p $AUTOREPO_HASHER_PREFIX$arch
    if ! [ -f "$initroot_stamp" ]; then
	# trying to reuse existing chroot; not doing --initroot-only if already done
	echo $arch hsh --target=$arch --with-stuff $AUTOREPO_HASHER_PREFIX$arch $AUTOREPO_HASHERARGS --apt-config=$aptconfbuild --initroot-only
	$arch hsh --target=$arch --with-stuff $AUTOREPO_HASHER_PREFIX$arch $AUTOREPO_HASHERARGS --apt-config=$aptconfbuild --initroot-only > "$logfile" 2>&1
	touch "$initroot_stamp"
	initroot_created=yes
    fi
    echo $arch hsh-install $AUTOREPO_HASHERARGS $AUTOREPO_HASHER_PREFIX$arch "$rpm"
    $arch hsh-install $AUTOREPO_HASHERARGS $AUTOREPO_HASHER_PREFIX$arch "$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 $AUTOREPO_HASHER_PREFIX$arch $AUTOREPO_HASHERARGS $AUTOREPO_HSH_ARGS --apt-config=$aptconfbuild --initroot-only
	    $arch hsh --target=$arch --with-stuff $AUTOREPO_HASHER_PREFIX$arch $AUTOREPO_HASHERARGS $AUTOREPO_HSH_ARGS --apt-config=$aptconfbuild --initroot-only > "$logfile" 2>&1
	    echo $arch hsh-install $AUTOREPO_HASHERARGS $AUTOREPO_HSH_INSTALL_ARGS $AUTOREPO_HASHER_PREFIX$arch "$rpm"
	    $arch hsh-install $AUTOREPO_HASHERARGS $AUTOREPO_HSH_INSTALL_ARGS $AUTOREPO_HASHER_PREFIX$arch "$rpm" >> "$logfile" 2>&1
	    if [ "$?" -gt 0 ]; then
		exit_status=5
	    fi
	fi
    fi
    return $exit_status
}

for arch in $GB_ARCH; do
    arch_build $arch "$@"
done

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

touch "$logdir"/build.success

for arch in $GB_ARCH; do
    [ -e "$logdir"/exclude.$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."
    exit $exit_status
fi

touch "$logdir"/unmets.success

for arch in $GB_ARCH; do
    initroot_stamp="$logdir"/initroot-${arch}.done
    rm -f "$initroot_stamp"
    if ! [ -e "$logdir"/exclude.$arch ]; then
	for rpm in $AUTOREPO_HASHER_PREFIX$arch/repo/$arch/RPMS.hasher/*.rpm; do
	    if [ -e "$rpm" ]; then # -e because w/o nullglob
		logfile="$logdir"/`basename $rpm`-${arch}-install.log
		if 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."
    exit $exit_status
fi

touch "$logdir"/install.success

exit $exit_status
