#! /bin/sh -efu
#
# Copyright (C) 2011  Aleksey Avdeev <solo@altlinux.ru>
#
# Common shell functions for cronbuild scripts.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
#

PROG_NAME="${0##*/}"

exit_err()
{
	#
	# $1 -- exit code
	# $2 -- msg
	#

	[ -n "$2" ] && printf "%s: %s\n" "$PROG_NAME" "$2"

	exit $1
}

get_mntname()
{
	#
	# Global vars:
	# mntname
	#

	if [ -z "$mntname" ]; then
		printf "solo\n"
	else
		printf "%s\n" "$mntname"
	fi
}

get_mntreponame()
{
	#
	# Global vars:
	# mntreponame
	#

	if [ -z "$mntreponame" ]; then
		printf "%s.git\n" "`get_packagename`"
	else
		printf "%s\n" "$mntreponame"
	fi
}

get_mntrepohost()
{
	#
	# Global vars:
	# mntrepohost
	#

	if [ -z "$mntrepohost" ]; then
		printf "git://git.altlinux.org/\n"
	else
		printf "%s\n" "$mntrepohost"
	fi
}

get_mntrepopath()
{
	#
	# Global vars:
	# mntrepopath
	#

	if [ -z "$mntrepopath" ]; then
		printf "people/%s/packages\n" "`get_mntname`"
	else
		printf "%s\n" "$mntrepopath"
	fi
}

get_mntrepourlpref()
{
	#
	# Global vars:
	# mntrepourlpref
	#

	if [ -z "$mntrepourlpref" ]; then
		printf "%s%s/\n" "`get_mntrepohost`" "`get_mntrepopath`"
	else
		printf "%s\n" "$mntrepourlpref"
	fi
}

get_mntrepourl()
{
	#
	# Global vars:
	# mntrepourl
	#

	if [ -z "$mntrepourl" ]; then
		printf "%s%s/\n" "`get_mntrepourlpref`" "`get_mntreponame`"
	else
		printf "%s\n" "$mntrepourl"
	fi
}

get_mntspecbranch()
{
	#
	# Global vars:
	# mntspecbranch
	#

	if [ -z "$mntsrpmsbranch" ]; then
		printf "ALT/%s/spec\n" "`get_packagename`"
	else
		printf "%s\n" "$mntspecbranch"
	fi
}

get_mntsrpmsbranch()
{
	#
	# Global vars:
	# mntsrpmsbranch
	#

	if [ -z "$mntsrpmsbranch" ]; then
		printf "ALT/%s/srpms\n" "`get_packagename`"
	else
		printf "%s\n" "$mntsrpmsbranch"
	fi
}

pull_mntsrpmsbranch()
{
	local srpmsbranch="`get_mntsrpmsbranch`"
	local repourl="`get_mntrepourl`"

	if [ -n "$srpmsbranch" -a -n "$repourl" ]; then
		git fetch "$repourl" "$srpmsbranch" || return $?

		local headcommit="`git rev-parse HEAD`"
		local fetchcommit="`git rev-parse FETCH_HEAD`"
		local basecommit="`git merge-base HEAD FETCH_HEAD`"

		case "$basecommit" in
			"$fetchcommit")
			return 0
			;;
			"$headcommit")
			git pull "$repourl" "$srpmsbranch" || return $?
			;;
			*)
			return 1
			;;
		esac
	fi
}

get_pullbranchmsg()
{
	#
	# $1 -- repourl
	# $2 -- repobranch
	# $3 -- thisbranch
	#

	printf "Merge branch '%s' of %s into %s" "$2" "$1" "$3"
}

get_specfile()
{
	local specfilename="$(gear --command sh -- -c 'printf %s "$gear_specfile"')"
	if [ -z "$specfilename" ] || ! [ -e "$specfilename" ]; then
		specfilename=''
	fi
	printf "%s\n" "$specfilename"
}

get_packagename()
{
	#
	# Global vars:
	# packagename
	#

	if [ -n "$packagename" ]; then
		printf "%s\n" "$packagename"
	else
		gear --command sh -- -c 'printf %s "$gear_pkg_name"'
	fi
}

get_packageverionrel()
{
	#
	# $1 -- specfile
	#
	# Return version-release

	get_packageepochverionrel "$1" \
		| sed -r 's/^[^:]+://'
}

get_packageepochverionrel()
{
	#
	# $1 -- specfile
	#
	# Return [epoch:]version-release

	local specfile="$1"
	if [ -z "$specfile" ]; then
		specfile="$packagespecname"
	fi

	sed -n -r '
	/^%changelog[[:space:]]*$/,/^[[:space:]]*$/{
		/^\*/s/^\*.+>[[:space:]]+([^[:space:]]+)[[:space:]]*$/\1/p
	}' "$specfile"
}

get_packageverion()
{
	#
	# $1 -- specfile
	#
	# Return version

	get_packageepochverionrel "$1" \
		| sed 's/-.*$//'
}

get_newversion()
{
	#
	# $1 -- specfile
	#
	# Return X.Y.(Z+1)

	local specfile="$1"
	if [ -z "$specfile" ]; then
		specfile="$packagespecname"
	fi

	# Version: X.Y.Z
	local version="`get_packageverionrel "$specfile"`"
	local versionXY="`echo $version \
		| sed -n -r '/^[[:space:]]*[0-9]+\.[0-9]+\.[0-9]+([-.][^[:space:]]+|)[[:space:]]*$/s/^[[:space:]]*([0-9]+\.[0-9]+)\.[0-9]+([-.][^[:space:]]+|)[[:space:]]*$/\1/p'`"
	local versionZ="`echo $version \
		| sed -n -r '/^[[:space:]]*[0-9]+\.[0-9]+\.[0-9]+([-.][^[:space:]]+|)[[:space:]]*$/s/^[[:space:]]*[0-9]+\.[0-9]+\.([0-9]+)([-.][^[:space:]]+|)[[:space:]]*$/\1/p'`"

	let versionZ=$versionZ+1

	printf "%s.%s\n" "$versionXY" "$versionZ"
}

get_commitmsg()
{
	#
	# $1 -- specfile
	#
	# Return commitmsg

	local specfile="$1"
	if [ -z "$specfile" ]; then
		specfile="$packagespecname"
	fi

	sed -n -r '
	/^%changelog[[:space:]]*$/,/^[[:space:]]*$/{
		/^%changelog[[:space:]]*$/!{
			/^\*/!p
			/^\*/{
				s/^\*.+>[[:space:]]+([^[:space:]]+)[[:space:]]*$/\1/p
				a \

			}
		}
	}' "$specfile"
}

new_commitmsg()
{
	# Get commitmsg
	local commitmsg="`get_commitmsg "$packagespecname"`"
	[ -n "$commitmsg" ] || exit_err 1 "ERR set commitmsg"

	printf "%s\n\ngear-update-tag -ac\n" "$commitmsg"
}

new_tagmsg()
{
	get_tagmsg
}

get_tagmsg()
{
	# Get packagename
	local packagename="`get_packagename "$packagespecname"`"
	[ -n "$packagename" ] || exit_err 1 "ERR set packagename"

	# Get packageverionrel
	local packageepochverionrel="`get_packageepochverionrel "$packagespecname"`"
	[ -n "$packageepochverionrel" ] || exit_err 1 "ERR set packageepochverionrel"

	printf "%s %s\n" "$packagename" "$packageepochverionrel"
}

new_tagname()
{
	get_tagname
}

get_tagname()
{
	# Get packagename
	local packagename="`get_packagename "$packagespecname"`"
	[ -n "$packagename" ] || exit_err 1 "ERR set packagename"

	# Get packageverionrel
	local packageverionrel="`get_packageverionrel "$packagespecname"`"
	[ -n "$packageverionrel" ] || exit_err 1 "ERR set packageverionrel"

	printf "ALT/%s/%s\n" "$packagename" "$packageverionrel"
}

get_sorcetagmsg()
{
	get_tagmsg \
		| sed -r 's/-[^-]+$//'
}

get_sorcetagname()
{
	get_tagname \
		| sed -r 's/-[^-]+$//'
}

get_release_commit()
{
	#
	# $1 -- fetch_source_commit
	# $2 -- old_source_commit
	# $3 -- check_release_commit function name
	# $4 -- err function name
	#

	local errfuncname
	if [ $# -ge 4 ] && [ -n "$4" ]; then
		errfuncname="$4"
	else
		errfuncname="exit_err"
	fi

	local checkreleasename
	if [ $# -ge 3 ] && [ -n "$3" ]; then
		checkreleasename="$3"
	else
		checkreleasename="check_release_commit"
	fi

	local fetchsourcecommit="$1"
	[ -n "$fetchsourcecommit" ] || $errfuncname 1 "ERR no oldsourcecommit seting"

	local oldsourcecommit="$2"
	[ -n "$oldsourcecommit" ] || $errfuncname 1 "ERR no oldsourcecommit seting"

	local sourcecommit=""
	local releasecommit=""
	git log --format='format:%H' "$oldsourcecommit..$fetchsourcecommit" \
		| while read -r sourcecommit
	do
		if [ "$sourcecommit" != "$oldsourcecommit" ]; then
			if [ -z "$releasecommit" ]; then
				releasecommit="`$checkreleasename "$sourcecommit"`"
				printf "%s" $releasecommit
			fi
		fi
	done
}

# Check packagespecname
if [ -z "$packagespecname" ]; then
	packagespecname="`get_specfile`"
fi
[ -n "$packagespecname" ] || exit_err 1 "ERR set specfile"
