#!/bin/ash -euf

DEBUG=1
TEST=
NOMAILS=

export LC_ALL=C LANG=C LANGUAGE=C

. "${0%/*}/../config"
. "$dist/incominger/functions"

dst="$incdir/align"
alignlist="$dbdir/list.align"

serv_i586="beeq1@mash"
serv_x86_64="beeq1@amd64"
serv_prefix=

archs="$rebuild_archs"
logdir="$logsdir/$PROG"
srclist="$filesdir/$PROG/queue"
loglist="$filesdir/$PROG/log"
db_lockdir="$dbdir/.lock"

debug() {
    [ -n "$DEBUG" ] || return 0
    printf 'DEBUG: [%s]: %s\n' "$(now)" "$@"
}

writelog() {
    local node="$1" f="$2" arch="$3" status="$4"
    logit "$arch	$node	$f	$status"
    debug "$node: $fn: $status"
}

exit_handler() {
    local rc=$?
    trap - EXIT
    [ ! -d "$db_lockdir/$PROG" ] || rm -rf -- "$db_lockdir"
    exit $rc
}

lockdb() {
    local i=0
    while ! mkdir "$db_lockdir" >/dev/null 2>&1; do
	sleep 3
	info "The directory is locked. Waiting 3 sec ..."
	i=$(($i + 1))
	if [ "$i" -gt 20 ]; then
	    trap - EXIT
	    error "The directory is locked too long: $dbdir"
	    exit 0
	fi
    done
    mkdir "$db_lockdir/$PROG"
}

> "$srclist.error"
for a in $archs; do
    serv="$(eval echo "\$serv_$a")"
    ssh -n "$serv" -- "set -e; max=0; uptime|tr -d \\ |sed -ne 's|^.*,loadaverage:||p'|tr \\, \\\\n|while read n; do [ \"\${n%%.*}\" = \"\$max\" ] || exit 1; done" || 
    {
	rc="$?"
	[ "$rc" != "255" ] || fatal "server unavailable: $serv"
	exit 0
    }
    echo > "$srclist.$a"
done

trap exit_handler HUP PIPE INT QUIT TERM EXIT
lockdb
while read pkg owner arch; do
    in_list "$arch" "$archs" || continue

    list="$(find "$stable_repo/files/SRPMS" -name "$pkg-*\.src\.rpm")"
    n="$(printf %s\\n "$list" |wc -l)"

    if [ "$n" -gt 1 ]; then
	srpm="$(printf %s\\n "$list" | xargs -r rpmrdups |cut -d\  -f1)"
    elif [ "$n" -eq 1 ]; then
	srpm="$list"
    else
	printf %s\\n "$pkg" >> "$loglist.error"
	error "$pkg not found"
	continue
    fi
    rpm_name="$(rpmquery -p --qf='%{NAME}' -- "$srpm")" || { error "rpmquery failed: $srpm"; continue; }
    [ "$pkg" = "$rpm_name" ] || continue # $owner - cheater
    ! grep -qsG "^$srpm[[:space:]]" "$srclist.$arch" || continue

    printf '%s\t%s\t%s\n' "$srpm" "$rpm_name" "$owner" >> "$srclist.$arch"
done < "$dbdir/list.align"
rm -rf -- "$db_lockdir"

for a in $archs; do
    mkdir -p -- "$logdir/$a" "$filesdir/$PROG" "$dst/$a"
    {
	serv="$(eval echo "\$serv_$a")"
	tmpdir="$(ssh "$serv" -- printf %s \"\$TMPDIR\")"

	ssh "$serv" -- "cat >\"$tmpdir/apt.conf\"" <<EOF
Dir::Etc::SourceList "$tmpdir/sources.list";
EOF
	ssh "$serv" -- "cat >\"$tmpdir/sources.list\"" <<EOF
rpm file:$serv_prefix$stable_repo noarch classic
rpm file:$serv_prefix$stable_repo $a classic
EOF
	ssh "$serv" -- "cat >\"$tmpdir/build\"" <<EOF
#!/bin/sh -euf
rc=0;
hsh -v --nprocs=1 --target="$a" --apt-config="$tmpdir/apt.conf" --mountpoints=/proc --no-repackage-source -- "$tmpdir" "$tmpdir/\$1" || rc=\$?;
rm -f -- "$tmpdir/\$1";
exit \$rc;
EOF
	ssh -n "$serv" -- "chmod +x -- \"$tmpdir/build\"; hsh --cleanup \"\$TMPDIR\";"
	while read f rpm_name owner; do
	    [ -n "$f" ] || continue

	    fn="${f##*/}"
	    log="$logdir/$a/$fn"

	    rsync -rlp \
		${DEBUG:+--log-format="DEBUG: [$(now)]: $serv:$tmpdir/ %i %n%L"} \
		"$f" "$serv:$tmpdir/$fn"

	    suffix=done
	    if ssh -n "$serv" -- "\"$tmpdir/build\" \"$fn\"" > "$log" 2>&1; then
		rsync -a --delete-after "$serv:$tmpdir/repo/$a/RPMS.hasher/" "$dst/$a/"
		ssh -n "$serv" -- "find \"$tmpdir/repo/SRPMS.hasher\" -type f -delete"
	    else
		suffix=failed
		printf '\t%s\n' "$owner" > "$log.info"
	    fi
	    mv -f "$log" "$log.$suffix"
	    printf '%s\n' "$rpm_name" >> "$loglist.$a"
	    writelog "$serv" "$fn" "$a" "$suffix"
	done < "$srclist.$a"
	rm -f "$srclist.$a"
    } &
done
wait

if [ -z "$NOMAILS" ]; then
    for a in $archs; do
	find "$logdir/$a/" -name "*.info" -exec "$helpers/sendmails" ${TEST:+-T} -m "align" -t "$a" -- \{\} \;
    done
fi
find "$logdir/" -type f \( -name '*.done' -o -name '*.failed' \) -exec bzip2 -f -- \{\} \;
find "$logdir/" -type f -name '*.info' -delete

lockdb
for a in "error" $archs; do
    [ -s "$loglist.$a" ] || continue
    while read pkg; do
	[ "$a" != "error" ] && arch="$a" || arch=".*"
	sed -ie "/^$pkg[[:space:]][^[:space:]]\+[[:space:]]$arch\$/d" "$dbdir/list.align"
    done < "$loglist.$a"
done
rm -rf -- "$db_lockdir"
