#!/bin/sh

export PATH=$HOME/bin:$PATH

# send mail on emergency exit if REPOCOP_ADMIN_MAIL is defined
REPOCOP_ADMIN_MAIL=viy@altlinux.org
ARCHDIFFHACK=/usr/share/repocop/pkgtests/unmet-dependency-build-missing-package/_archdiff
REPOCOP_WORKDIR=$HOME/.repocop
ARCHDIFFDIR=$REPOCOP_WORKDIR/testcache/_archdiff
BRANCH=sisyphus
DISTROMAP_REPOSITORY=altlinux



PROG="${0##*/}"
quiet=

DO_rsync=
DO_archdiff=yes
DO_beehive=
DO_collect=yes
DO_posttest=yes
DO_report=yes
DO_diff=yes
DO_cybertalk=
DO_prometheus=
DO_distrodb=yes
DO_archive=yes
DO_altnode=yes

# import beehive logs on Tuesdays
# [ `date +%u` = 2 ] && DO_beehive= 

REPOCOP_ARCH=x86_64
REPOCOP_RUN_COLLECT_OPTS=
REPOCOP_RUN_POSTTEST_OPTS=
REPOCOP_REPORT_PROMETHEUS_OPTS=
REPOCOP_REPORT_ACL_OPTS=

[ -e $REPOCOP_WORKDIR/daily.conf ] && . $REPOCOP_WORKDIR/daily.conf

REPODIR=${REPODIR:-~/Sisyphus}
ALLRPMS=${ALLRPMS:-$REPODIR/files/SRPMS $REPODIR/files/noarch/RPMS $REPODIR/files/$REPOCOP_ARCH/RPMS}
SRPMS=${SRPMS:-$REPODIR/files/SRPMS}
FTPDIR=${FTPDIR:-/var/ftp}
ALTNODE_DIR=${ALTNODE_DIR:-$FTPDIR/altnode/`whoami`}
PUBDIR=${PUBDIR:-$FTPDIR/pub/repocop}
PUB_PROMETHEUS1_DIR=${PUB_PROMETHEUS1_DIR:-$PUBDIR/prometeus}
PUB_PROMETHEUS2_DIR=${PUB_PROMETHEUS2_DIR:-$PUBDIR/prometheus2}
ARCHIVE_DIR=${ARCHIVE_DIR:-$PUBDIR/data}
DISTRODB_DIR=${DISTRODB_DIR:-$PUBDIR/data}
REPOCOP_METADATADIR=$REPOCOP_WORKDIR/metadata

Unlink_Except()
{
    local kept_file="$1"
    shift;
    for i in "$@"; do
	[ "$kept_file" != "$i" ] && ! [ -L "$i" ] && rm -f -- "$i"
    done
}

Message()
{
	[ -z "$quiet" ] || return 0
	printf %s\\n "$*"
}

Fatal()
{
	printf %s\\n "$PROG: $*" >&2
	exit 1
}

_emergency_exit()
{
    if [ -n "$DO_altnode" ] && [ -z "$NO_altnode" ]; then
	_altnode_stamp_common
	echo "$*" > $ALTNODE_DIR/repocop_summary
	echo fail > $ALTNODE_DIR/status
    fi
    if [ -n "$REPOCOP_ADMIN_MAIL" ]; then
	local adate=$(date +"%Y%m%d")
	add_repocop_log=
	! [ -f repocop-daily.log ] || add_repocop_log="-a repocop-daily.log"
	(echo "Repocop for $BRANCH have a problem:"; echo "$*"; cat <<EOF
--
Sincerely yours,
Repocop service.
EOF
	) | mutt -x -s "repocop for $BRANCH: aborted at $adate" $add_repocop_log -- "$REPOCOP_ADMIN_MAIL"
    fi
    Fatal "$@"
}

do_rsync()
{
    Message "rsync (nothing to do)..."
}

do_archdiff()
{
    if [ -x $ARCHDIFFHACK ]; then
	Message "running _archdiff hack..."
	$ARCHDIFFHACK "$ARCHDIFFDIR" "$REPODIR" $REPOCOP_ARCH || _emergency_exit "Failed: $ARCHDIFFHACK $ARCHDIFFDIR $REPODIR"
    fi
}

do_beehive()
{
    cmd=/usr/bin/repocop-process-build-logs
    if [ -x $cmd ]; then
	if [ -z "$NO_beehive_rsync" ]; then
	    Message "run (beehive log collect)..."
	    repocop-rsync-beehive-logs || _emergency_exit "Failed: repocop-rsync-beehive-logs"
	fi
	Message "run (beehive log process)..."
	$cmd -v || _emergency_exit "Failed: $cmd"
    else
	Message "skip (beehive) - $cmd not found"
    fi
}

do_collect()
{
    Message "run (collect)..."
    # if repocop-run exited abnormally it should just stop
    repocop-run --no-posttest $REPOCOP_RUN_COLLECT_OPTS $ALLRPMS || _emergency_exit "Failed: repocop-run --no-posttest $REPOCOP_RUN_COLLECT_OPTS $ALLRPMS"
    vacuum_opt=--novacuum
    [ `date +%u` = 3 ] && vacuum_opt=--vacuum
    repocop-purge-except --last-run $vacuum_opt || _emergency_exit "Failed: repocop-purge-except --last-run $vacuum_opt"
}


do_posttest()
{
    Message "run (posttest)..."
    # if repocop-run exited abnormally it should just stop
    repocop-run --no-collect --posttest --distrotest $REPOCOP_RUN_POSTTEST_OPTS || _emergency_exit "Failed: repocop-run --no-collect --posttest --distrotest $REPOCOP_RUN_POSTTEST_OPTS"
}

do_diff()
{
    cmd=/usr/bin/repocop-report-diff
    if [ -x $cmd ]; then
	Message "diff..."
	$cmd --write-report $REPOCOP_REPORT_ACL_OPTS $REPOCOP_WORKDIR/testcache/specfile
    fi
}

do_report()
{
    cmd=/usr/bin/repocop-report-txt
    if [ -x $cmd ]  && [ -z "$NO_report_txt" ]; then
	Message "report (txt)..."
	$cmd --report experimental $REPOCOP_REPORT_ACL_OPTS $REPOCOP_REPORT_TXT_OPTS
    fi
    cmd=/usr/bin/repocop-report-html
    if [ -x $cmd ]  && [ -z "$NO_report_html" ]; then
	Message "report (html)..."
	$cmd --report experimental $REPOCOP_REPORT_ACL_OPTS $REPOCOP_REPORT_HTML_OPTS
    fi
    rsync -a --delete-after $REPOCOP_WORKDIR/reports $PUBDIR/
}

do_cybertalk()
{
    cmd=/usr/bin/repocop-report-email
    if [ -x $cmd ] && [ -n "$REPOCOP_CYBERTALK_EMAIL" ]; then
	Message "cybertalk..."
	$cmd "$REPOCOP_CYBERTALK_EMAIL"
    fi
}

# ----- prometheus -----------
do_prometheus()
{
    cmd=/usr/bin/repocop-report-prometheus-dump
    if [ -x $cmd ]; then
	Message "prometheus..."
	mkdir -p $PUB_PROMETHEUS1_DIR
	$cmd > $PUB_PROMETHEUS1_DIR/repocop-prometeus.sql
	rm -f $PUB_PROMETHEUS1_DIR/repocop-prometeus.sql.gz
	gzip -9 $PUB_PROMETHEUS1_DIR/repocop-prometeus.sql
	stat $PUB_PROMETHEUS1_DIR/repocop-prometeus.sql.gz --format %y > $PUB_PROMETHEUS1_DIR/timestamp
    fi
    cmd=/usr/bin/repocop-report-prometheus2
    if [ -x $cmd ]; then
	Message "prometheus2 (text sql)..."
	CURDATA=`date '+%Y%m%d'`
	mkdir -p $PUB_PROMETHEUS2_DIR
	rm -f $PUB_PROMETHEUS2_DIR/prometheus2*.sql
	$cmd --branch $BRANCH > $PUB_PROMETHEUS2_DIR/prometheus2-$CURDATA.sql
	ln -sf $PUB_PROMETHEUS2_DIR/prometheus2-$CURDATA.sql $PUB_PROMETHEUS2_DIR/prometheus2.sql
	rm -f $PUB_PROMETHEUS2_DIR/prometheus2-patches-*.sql
	cmd=/usr/bin/repocop-report-prometheus2-patches
	$cmd --branch $BRANCH > $PUB_PROMETHEUS2_DIR/prometheus2-patches-$CURDATA.sql
	ln -sf $PUB_PROMETHEUS2_DIR/prometheus2-patches-$CURDATA.sql $PUB_PROMETHEUS2_DIR/prometheus2-patches.sql
    fi
    cmd=/usr/bin/repocop-report-prometheus2-sqlite
    if [ -x $cmd ]; then
	Message "prometheus2 (sqlite)..."
	CURDATA=`date '+%Y%m%d'`
	mkdir -p $PUB_PROMETHEUS2_DIR
	rm -f $PUB_PROMETHEUS2_DIR/prometheus2-$CURDATA.sqlite.bz2
	$cmd --branch $BRANCH ${DISTROMAP_COMPONENT:+--component "$DISTROMAP_COMPONENT"} --out $PUB_PROMETHEUS2_DIR/prometheus2-$CURDATA.sqlite
	bzip2 $PUB_PROMETHEUS2_DIR/prometheus2-$CURDATA.sqlite
	ln -sf $PUB_PROMETHEUS2_DIR/prometheus2-$CURDATA.sqlite.bz2 $PUB_PROMETHEUS2_DIR/prometheus2.sqlite.bz2
	Unlink_Except $PUB_PROMETHEUS2_DIR/prometheus2-$CURDATA.sqlite.bz2 $PUB_PROMETHEUS2_DIR/prometheus2-*.sqlite.bz2
    fi
}
# ---- end prometheus ----

Pack_and_Rotate()
{
    local destdir=$1
    local fileprefix=$2
    shift;shift;
    mkdir -p $destdir/ || _emergency_exit "Pack_and_Rotate: Failed: mkdir -p $destdir/"
    local CURDATA=`date '+%Y%m%d'`
    local suffix=${REPOCOP_ARCHIVE_SUFFIX:-gz}
    # tar czf too slow for sequential gzip
    local compress_program=pigz
    case $suffix in
	gz) compress_program=pigz ;;
	bz*) compress_program=bzip2 ;;
	xz) compress_program=xz ;;
	zst) compress_program=pzstd ;;
    esac
    rm -rf $destdir/$fileprefix-$CURDATA.tar.$suffix
    tar --use-compress-program="$compress_program" -cf $destdir/$fileprefix-$CURDATA.tar.$suffix "$@" \
	|| _emergency_exit "Pack_and_Rotate: Failed: tar czf $destdir/$fileprefix-$CURDATA.tar.$suffix "$@""
    ln -sf $fileprefix-$CURDATA.tar.$suffix $destdir/$fileprefix-current.tar.$suffix
    Unlink_Except $destdir/$fileprefix-$CURDATA.tar.$suffix $destdir/$fileprefix*
}

do_distrodb()
{
    cmd=/usr/bin/repocop-report-distrodb
    if [ -x $cmd ]; then
	Message "distrodb..."
	$cmd --branch $BRANCH ${DISTROMAP_COMPONENT:+--component "$DISTROMAP_COMPONENT"}
	distrodb_main_file=repocop-distrodb-$BRANCH${DISTROMAP_COMPONENT:+-$DISTROMAP_COMPONENT}
	distrodb_extra_file=repocop-distrodb-extra-$BRANCH${DISTROMAP_COMPONENT:+-$DISTROMAP_COMPONENT}
	# pushd ~ due to *.raw
	pushd ~
	    Pack_and_Rotate $DISTRODB_DIR $distrodb_extra_file  -C ~ .cache/distrodb/$DISTROMAP_REPOSITORY/$BRANCH/*.raw
	    Pack_and_Rotate $DISTRODB_DIR $distrodb_main_file  -C ~ --exclude '*.raw*' .cache/distrodb/$DISTROMAP_REPOSITORY/$BRANCH
	popd
    fi
}

do_archive()
{
    Message "archive..."
    _wd_base=`basename "$REPOCOP_WORKDIR"`
    _wd_dir=`dirname "$REPOCOP_WORKDIR"`
    Pack_and_Rotate $ARCHIVE_DIR repocop-data  -C "$_wd_dir" "$_wd_base"/testcache "$_wd_base"/db "$_wd_base"/testdb ${DO_archive_data_reports:+"$_wd_base"/reports}
    if [ -z "$NO_archive_extra" ]; then
	! [ -d $REPOCOP_WORKDIR/reports/diff ] || Pack_and_Rotate $ARCHIVE_DIR repocop-report -C "$_wd_dir" "$_wd_base"/reports/diff "$_wd_base"/reports/txt
	! [ -d $REPOCOP_WORKDIR/testcache/watch ] || Pack_and_Rotate $ARCHIVE_DIR repocop-watchfiles -C $REPOCOP_WORKDIR/testcache watch
	! [ -d $REPOCOP_WORKDIR/testcache/specfile ] || Pack_and_Rotate $ARCHIVE_DIR repocop-specfiles -C $REPOCOP_WORKDIR/testcache specfile
	[ -f $REPOCOP_WORKDIR/db/freedesktop-desktop.db ] || rm -f $ARCHIVE_DIR/freedesktop-desktop.db
	! [ -f $REPOCOP_WORKDIR/db/freedesktop-desktop.db ] || ln -f $REPOCOP_WORKDIR/db/freedesktop-desktop.db $ARCHIVE_DIR/
    fi
}

_altnode_stamp_common()
{
    echo repocop > $ALTNODE_DIR/type
    echo $BRANCH > $ALTNODE_DIR/platform
    echo ${DISTROMAP_COMPONENT:+$DISTROMAP_COMPONENT/}$BRANCH > $ALTNODE_DIR/repository
    echo ${PUBDIR##$FTPDIR/}/reports > $ALTNODE_DIR/relative_path
    date +'%F %T %Z' > $ALTNODE_DIR/datastring
}

do_altnode()
{
    Message "altnode..."
    _altnode_stamp_common
    repocop-report-total-messages > $ALTNODE_DIR/repocop_summary
    echo ok > $ALTNODE_DIR/status
}

while [ "$#" -ge 1 ]; do
	case "$1" in
		-q|--quiet) quiet=-q
			;;
		-v|--verbose) quiet=
			;;
		-h|--help) show_help
			;;
		--) shift; break
			;;
		--no-[a-z]*)
			arg="NO_${1##--no-}"
			eval $arg=1
			;;
		--[a-z]*)
			arg="DO_${1##--}"
			eval $arg=1
			;;
		*) Fatal "unrecognized option: $1"
			;;
	esac
	shift
done

latest_symlink=
if [ -n "$REPO_LATEST_SYMLINK" ]; then
    [ -L "$REPO_LATEST_SYMLINK" ] || _emergency_exit "Bad REPO_LATEST_SYMLINK $REPO_LATEST_SYMLINK: not a symlink."
    latest_symlink=`readlink "$REPO_LATEST_SYMLINK"`
    [ -n "latest_symlink" ] || _emergency_exit "failed to readlink $REPO_LATEST_SYMLINK"
    if [ -e $REPOCOP_METADATADIR/repo_symlink_processed ]; then
	processed_symlink=`cat $REPOCOP_METADATADIR/repo_symlink_processed`
	if [ "$latest_symlink" = "$processed_symlink" ]; then
	    exit 0
	fi
    fi
    repocop-workdir-lock --is-locked-by-others $$ && exit 0 ||:
fi
repocop-workdir-lock --lock $$ || _emergency_exit "can't lock the workdir. "`repocop-workdir-lock $$`

# Failsafe tmp cleanup
me=`whoami`
[ -d /tmp/.private/$me ] && for i in /tmp/.private/$me/*; do rm -rf $i; done

[ -n "$DO_rsync" ] && [ -z "$NO_rsync" ] && do_rsync
[ -n "$DO_archdiff" ] && [ -z "$NO_archdiff" ] && do_archdiff
[ -n "$DO_beehive" ] && [ -z "$NO_beehive" ] && do_beehive
[ -n "$DO_collect" ] && [ -z "$NO_collect" ] && do_collect
[ -n "$DO_posttest" ] && [ -z "$NO_posttest" ] && do_posttest
[ -n "$DO_diff" ] && [ -z "$NO_diff" ] && do_diff
[ -n "$DO_report" ] && [ -z "$NO_report" ] && do_report
[ -n "$DO_cybertalk" ] && [ -z "$NO_cybertalk" ] && do_cybertalk
[ -n "$DO_prometheus" ] && [ -z "$NO_prometheus" ] && do_prometheus
[ -n "$DO_distrodb" ] && [ -z "$NO_distrodb" ] && do_distrodb
[ -n "$DO_archive" ] && [ -z "$NO_archive" ] && do_archive
[ -n "$DO_altnode" ] && [ -z "$NO_altnode" ] && do_altnode

if [ -n "$REPO_LATEST_SYMLINK" ]; then
    mkdir -p $REPOCOP_METADATADIR/
    echo "$latest_symlink" > $REPOCOP_METADATADIR/repo_symlink_processed
fi

repocop-workdir-lock --unlock $$
exit 0
