#!/bin/bash
# 2003-2010, 2012, 2015 (c) Etersoft www.etersoft.ru
# Author: Vitaly Lipatov <lav@etersoft.ru>
# Public domain
#
# BPH - backport package with hasher checking

# Used ROOTDIR if defined (for non ALT systems)

# load common functions, compatible with local and installed script
. `dirname $0`/../share/eterbuild/functions/common
load_mod repl rpm git buildsrpm spec


#############################

# FIXME: CURRENTBRANCHNAME??
Usage="Usage: $name [-r -u -U -n -i -m -v -q] [-$CURRENTBRANCHNAME] [-b REPONAME] spec..."
function mygetopts()
{
name=${0##*/}
Descr="$name (BackPort and Hasher) - backports spec and rebuild it"

phelp()
{
	echog "$Descr"
	echog "$Usage"
	echo  "Usage: rpmbph [GIRAR] -b $EXAMPLEALTDISTRVERSION for backport to ALT Linux $EXAMPLEALTDISTRVERSION and so on"
	echo
	echog "Options:"
	echog "   -u           sign and upload after build" # will pass to rpmbs/rpmbsh
	echog "   -n           do not build in hasher"
	echog "   -i           install built packages in test hasher" # will pass to rpmbs/rpmbsh
	echog "   -b REPONAME  binary repository name (4.1, p5, t6 and so on)"
	echo
	echog "Ext. options:"
#	echog "   -r           remote build" # will pass to rpmbs/rpmbsh
	echog "   -v           more verbose"
	echog "   -q           quiet"
	echo
	echog "Examples:"
	echog " $ rpmbph -b $EXAMPLEALTDISTRVERSION -n -u  - backport to $EXAMPLEALTDISTRVERSION and ask to build it"
#	echog "Set ROOTDIR variable for backport to the other system"
#	echog " -m - send result via e-mail"
}

# FIXME: has difference between
UPLOADARG=
while getopts :hnvqb: opt; do
    case $opt in
        h) phelp; exit 0 ;;
        n) NOBUILD=1 ;;
        u) UPLOADARG="-$opt" ;;
        v) VERBOSE=1 ;;
        b) BINARYREPONAME=$OPTARG ;;
        q) QUIET=1 ;;
        +?) echog "$name: options should not be preceded by a '+'." 1>&2; exit 2;;
        ?) OPTIND=$((OPTIND-1)); break;
    esac
done

# remove args that were options
if [ $# -gt 0 ]; then
	shift $((OPTIND - 1))
fi

# pass other options to RPM (exclude -v):
LISTRPMARGS="$UPLOADARG $(drop_args "$*" v n q)"
}

set_girar_host $1 && shift

parse_cmd_pre_spec "$@"
mygetopts $LISTARGS

# see functions/alt:set_binaryrepo() for BINARYREPONAME
set_binaryrepo $MENV

test -z "$LISTNAMES" && fatal "file not found in '$@'"

if [ "$PKGVENDOR" = "alt" ] ; then
	MDISTR=$MENV
	[ "$MDISTR" = "SS" ] && fatal "It makes no sense to backport to Sisyphus (You need to try with -b $EXAMPLEALTDISTRVERSION)."
	# override by defined target version
	DISTRVERSION=$BINARYREPO
else
	MDISTR=LOCAL
fi

[ -n "$VERBOSE" ] && echo "DISTRVERSION=$DISTRVERSION LISTRPMARGS=$LISTRPMARGS"

if [ -z "$BUILDCOMMAND" ] ; then
	BUILDCOMMAND="$ETERBUILDBIN/rpmbsh $GIRARHOST"
	[ -n "$NOBUILD" ] && BUILDCOMMAND="$ETERBUILDBIN/rpmbs $GIRARHOST"
fi

# set SPECDIR from LISTNAMES if empty
[ -n "$SPECDIR" ] || set_specdir $LISTNAMES

# if run for ALT inside gear repo, just create backported spec
if [ "$PKGVENDOR" = "alt" ] && is_gear $SPECDIR ; then
	[ -f "$LISTNAMES" ] || fatal "Run with one spec inside gear repo"

	# set branch name
	USEBRANCH=$BINARYREPO
	SPEC=$LISTNAMES
	BPSPEC=$SPEC.$USEBRANCH

	# support for obsoleted M?? names
	OLDBRANCH=$MDISTR
	if [ "$OLDBRANCH" != "$USEBRANCH" ] ; then
		if is_exist_branch $OLDBRANCH ; then
			echo "Exists $OLDBRANCH branch, will use it instead $USEBRANCH"
			USEBRANCH=$OLDBRANCH
		fi
		# hack about p5, M50 -> p5
		#if [ "$USEBRANCH" = "M50" ] && is_exist_branch p5 ; then
		#	USENUMBRANCH=p5
		#	echo "Exists $USENUMBRANCH branch, will use it instead $USEBRANCH"
		#	USEBRANCH=$USENUMBRANCH
		#fi
	fi

	[ -f "$BPSPEC" ] && fatal "File $BPSPEC is already exists, check it and remove"

	CURBRANCH=$(get_current_branch)

	if [ "$CURBRANCH" = "$USEBRANCH" ] || [ "$CURBRANCH" = "$OLDBRANCH" ] ; then
		fatal "You are already in backported branch $CURBRANCH. Run rpmbph in sisyphus or master branch only."
	fi

	# Create branch if not exist yet
	if ! is_exist_branch $USEBRANCH ; then
		docmd git branch $USEBRANCH
	fi

	# Only one spec supported
	cp -f $LISTNAMES $BPSPEC || fatal
	docmd $ETERBUILDBIN/rpmbps -b $BINARYREPO $BPSPEC || fatal

	docmd git checkout $USEBRANCH || fatal "Can't checkout branch $USEBRANCH. Use $BPSPEC manually or remove it."
	# TODO: check result message for merge?
	# Use heads/ against warning: refname 'branch-name' is ambiguous
	docmd git merge --no-ff heads/$CURBRANCH
	mv -f $BPSPEC $SPEC || fatal
	# FIXME: Ctrl-\ and q will cancelled less with return error code
	if [ -z "$QUIET" ] && tty -s && ! ( echo "etersoft-build-utils INFO: Please check diff for backported spec:" ; echo "# etersoft-build-utils NOTE: You can press Ctrl-\ before quit for cancel process."; echo ; git diff $USEBRANCH ) | less; then
		#git checkout $SPEC $MDISTR
		#git checkout $CURBRANCH
		fatal "Cancelled by user. You are still in $USEBRANCH branch with modified spec."
	fi
	docmd git add $SPEC
	if ! git_commit_ignore_nothing -a -m "backported to $USEBRANCH as $(get_version $SPEC)-$(get_release $SPEC) (with rpmbph script)" ; then
		#git checkout $CURBRANCH
		fatal "Commit error. You are still in $CURBRANCH branch with modified and uncommitted spec file."
	fi
	docmd $BUILDCOMMAND $MENVARG $LISTRPMARGS $UPLOADARG $SPEC || { git checkout $CURBRANCH ; fatal "Can't build" ; }
	docmd git checkout $CURBRANCH
	exit $?
fi

# handle src.rpm and spec both, LISTBUILT - result with full paths to src.rpms
pack_src_rpm $LISTNAMES

export RPMTOPDIR=$(mktemp -d || fatal "can't create tmp dir")
mark_file_to_remove $RPMTOPDIR

# prevent gear detecting (operate inside our dir)
export IGNOREGEAR=1
# NOTE: we can do cd to some other dir...

for i in $LISTBUILT ; do
	uni_rpminstall $i
	# remove primary src.rpm only if src.rpm was not primary
	rhas "$LISTNAMES" "$i" || rm -f $i

	SPECNAME=$RPMTOPDIR/SPECS/$(spec_by_srpm $i)
	test -f "$SPECNAME" || fatal "Spec $SPECNAME is not found"
	docmd $ETERBUILDBIN/rpmbps -b $BINARYREPO $SPECNAME

	docmd $BUILDCOMMAND -b $BINARYREPO $LISTRPMARGS $UPLOADARG $SPECNAME || fatal "Can't build"
	uni_rpmrm $SPECNAME || true
done

rm -rf $RPMTOPDIR
remove_file_from_remove $RPMTOPDIR
