#!/bin/bash
# 2003-2010, 2012, 2015, 2016, 2017 (c) Etersoft www.etersoft.ru
# Author: Vitaly Lipatov <lav@etersoft.ru>
# Public domain
#
# BPS - backport package spec

# 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



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

Usage="Usage: $name [-b REPONAME] spec"
function mygetopts()
{
name=${0##*/}
Descr="$name (BackPort Spec) - backport spec"

phelp()
{
	echog "$Descr"
	echog "$Usage"
	echo  "Usage: rpmbps -b $EXAMPLEALTDISTRVERSION for backport to ALT Linux $EXAMPLEALTDISTRVERSION and so on"
	echo
	echog "Options:"
	echog "   -b REPONAME  binary repository name (p8, t7 and so on)"
#	echog "   -q           quiet"
	echo
	echog "Examples:"
	echog " $ rpmbps -b $EXAMPLEALTDISTRVERSION - backport spec to $EXAMPLEALTDISTRVERSION form"
}

# FIXME: has difference between
while getopts :hb: opt; do
    case $opt in
        h) phelp; exit 0 ;;
        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
	[ "$OPTIND" -gt 0 ] && shift $(($OPTIND - 1))
fi

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

parse_cmd_pre_spec "$@"
mygetopts $LISTARGS
# see functions/alt:set_binaryrepo() for BINARYREPONAME
set_binaryrepo $MENV

# TODO
SPECNAME="$LISTNAMES"
test -f "$SPECNAME" || fatal "file '$SPECNAME' is not found"

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
	# then ROOTDIR is used?
	MDISTR=LOCAL
fi

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

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

# TODO
BASERELEASE=$(get_numrelease $SPECNAME)
RELEASE=$(get_release $SPECNAME)
BUILDNAME=$(get_name $SPECNAME)

ADDFIXCOMMAND=
ADDREQUIRES=

echo "Converting spec $(basename $SPECNAME) to $DISTRVERSION ($MDISTR) ..."

# TODO: check if spec is already backported by line:
# # This spec is backported 
# and by release

# Set buildreq
if [ "$PKGVENDOR" = "alt" ] ; then
	# FIXME: needed for some backport level...
	#BUILDREQ="BuildRequires: rpm-build-compat >= 0.95"
	BUILDREQ=

	# FIXME: use separate macro list
	# FIXME: check for all rpm-build-compat macro list
	if grep -q configure32 $SPECNAME ; then
		BUILDREQ="BuildRequires: rpm-build-compat >= 1.9.0"
	elif grep -q "\(_cupslibdir\|_sudoers\)" $SPECNAME ; then
		BUILDREQ="BuildRequires: rpm-build-compat >= 1.7.25"
	elif grep -q _sharedstatedir $SPECNAME ; then
		BUILDREQ="BuildRequires: rpm-build-compat >= 1.7.24"
	fi

	if is_backported_release $RELEASE ; then
		# TODO: do not use mask M00
		docmd set_release $SPECNAME "$(echo "$RELEASE" | sed -e "s|M[0-9][0-9][PCT]|$MDISTR|")"
	else
		# Change release according to alt policy with extensions
		# General rule: alwars alt(N-1).MM.(N)
		docmd set_release $SPECNAME $(get_txtrelease $SPECNAME)$(decrement_release $BASERELEASE).$MDISTR.$BASERELEASE
	fi

	ADDDEF=""
	CLEANTEXT=""
else
	# All non ALT Linux distros
	# disabled by Lav https://bugs.etersoft.ru/show_bug.cgi?id=13034
	# docmd $ETERBUILDBIN/rpmcs --skip-reqs $SPECNAME

	BUILDREQ="BuildRequires:"
	# Korinf hack
	if [ $(basename $SPECNAME) != "eepm.spec" ] ; then
		if ! grep -q "BuildRequires:.*rpm-build-altlinux-compat" $SPECNAME ; then
			# Need our compat package and disable strong patch checking
			BUILDREQ="$BUILDREQ rpm-build-altlinux-compat >= 0.95"
		fi
	fi

	# TODO: add support for external hooks (from config dir)

	if build32on64 ; then
		[ "$DISTRNAME" = "Debian" ] && ! version_more_version $DISTRVERSION 8 && BUILDREQ="$BUILDREQ ia32-libs-dev" && ADDREQUIRES="$ADDREQUIRES ia32-libs"
		[ "$DISTRNAME" = "AstraLinux" ] && BUILDREQ="$BUILDREQ ia32-libs-dev gcc-multilib" && ADDREQUIRES="$ADDREQUIRES ia32-libs"
		[ "$DISTRNAME" = "Ubuntu" ] && ! version_more_version $DISTRVERSION 12.04 && BUILDREQ="$BUILDREQ ia32-libs-dev" && ADDREQUIRES="$ADDREQUIRES ia32-libs"
		[ "$DISTRNAME" = "CentOS" ] && version_more_version $DISTRVERSION 6 && BUILDREQ="$BUILDREQ glibc-devel(x86-32)"
		[ "$DISTRNAME" = "Scientific" ] && version_more_version $DISTRVERSION 6 && BUILDREQ="$BUILDREQ glibc-devel(x86-32)"
		[ "$DISTRNAME" = "GosLinux" ] && version_more_version $DISTRVERSION 6 && BUILDREQ="$BUILDREQ glibc-devel(x86-32)"
		[ "$DISTRNAME" = "SLED" ] && version_more_version $DISTRVERSION 11 && BUILDREQ="$BUILDREQ glibc-devel-32bit gcc-32bit"
		[ "$DISTRNAME" = "SUSE" ] && version_more_version $DISTRVERSION 11 && BUILDREQ="$BUILDREQ glibc-devel-32bit gcc-32bit"
	fi

	# hack against very straight patch command
	FIXPATCHFUZZ="%define _default_patch_fuzz 3"
	# see install in Korinf, need concatenate
	BUILDREQ="$BUILDREQ make gcc\n$FIXPATCHFUZZ"
	# (do not modify BUILDREQ anymore)

	# Hack for allow repack on x86_64 packages with ExclusiveArch: %{ix586}
	[ "$SYSARCH" = "x86_64" ] && subst "s|^ExclusiveArch:.*||g" $SPECNAME

	[ -z "$BUILDCOMMAND" ] && BUILDCOMMAND=$ETERBUILDBIN/rpmbb
	TXTRELEASE=$(get_txtrelease $SPECNAME)
	# HACK: Override release with KORINFTARGETRELEASE if set
	[ -z "$KORINFTARGETRELEASE" ] || TXTRELEASE=$KORINFTARGETRELEASE

	if is_backported_release $RELEASE ; then
		# TODO: do not use mask M00
		docmd set_release $SPECNAME $TXTRELEASE"$(echo "$BASERELEASE" | sed -e "s|M[0-9][0-9][PCT].*||")"$PKGVENDOR
	else
		docmd set_release $SPECNAME $TXTRELEASE$BASERELEASE$PKGVENDOR
	fi
	test -z "$VERBOSE" || echo "Build package with release $TXTRELEASE"
	ADDDEF="%defattr(-, root, root)"
	CLEANTEXT=""
fi

# Do not add BuildReq if already exist
cat $SPECNAME | grep rpm-build-compat &>/dev/null && BUILDREQ=""

# fix readlink -m, introduced by new libtool and missed in RHEL4 (replace with readlink -f)
if [ "$DISTRNAME/$DISTRVERSION" = "ASPLinux/11.2" ] ; then
	test -z "$VERBOSE" || echo "Add subst readlink -m"
	ADDFIXCOMMAND="$ADDFIXCOMMAND
%__subst 's|readlink -m|readlink -f|g' libtool ltmain.sh"
fi

# fix readlink -mv, introduced by new libtool and missed in FreeBSD (replace with realpath)
if [ "$PKGVENDOR" = "freebsd" ] ; then
	test -z "$VERBOSE" || echo "Add subst readlink -mv"
	ADDFIXCOMMAND="$ADDFIXCOMMAND
%__subst 's|readlink -mv|realpath|g' libtool configure ltmain.sh"
fi

#if build32on64 ; then
#	test -z "$VERBOSE" || echo "Add remove_optflags -m64"
#	ADDFIXCOMMAND="$ADDFIXCOMMAND
#%remove_optflags -m64"
#fi

# fix mktemp using for MCBC
if [ "$PKGVENDOR" = "mcbc" ] ; then
	test -z "$VERBOSE" || echo "Add subst mktemp -dt"
	ADDFIXCOMMAND="$ADDFIXCOMMAND
%__subst 's|mktemp -dt|mktemp -d|g' configure ; %__subst 's|readlink -mv|ls -1|g' configure ltmain.sh"
fi


LISTBUILDDEP=`print_buildreq $SPECNAME`
LISTREQDEP="`print_pkgreq $SPECNAME` $ADDREQUIRES"
LISTDEP=`echo $LISTBUILDDEP $LISTREQDEP | xargs -n1 echo | sort -u`
LISTGROUP=`eval_spec $SPECNAME | grep "^Group" | sed -e "s|^.*:||g"  | xargs -n1 echo | sort -u`


# Build replacement rules for spec
ALLREPLRULES=""

if [ -n "$VERBOSE" ] ; then
	echo
	echo "Checking req names for"
	echo "$LISTDEP"
	echo
	echo "Used replacement files: "
	print_pkgrepl_list
fi

[ -n "$VERBOSE" ] && echo && echo "Used rules:"
pkgrepl_list=$(print_pkgrepl_list)
for i in $LISTDEP ; do
	tolocal_anyrepl $i $pkgrepl_list || continue
	#NRL="s!\(.*Req.*\)$REPLRULE1\( |,|\$\)!\1$REPLRULE2\2!g"
	NRL="s!(.*Req.*)$ALTPKGNAME( |,|}|\$)!\1$TARGETPKGNAME\2!g"
	[ -n "$VERBOSE" ] && echo "    $NRL from $USEDPKGREPL"
	ALLREPLRULES="$ALLREPLRULES $NRL;"
done

# Build replacement rules for spec
[ -n "$VERBOSE" ] && echo && echo -e "Checking group names for\n$LISTGROUP"
ALLGRPREPLRULES=""
grprepl_list=$(print_grprepl_list)
for i in $LISTGROUP ; do
	tolocal_anyrepl $i $grprepl_list || continue
	#NRL="s!\(Group.*\)$REPLRULE1\( |,|\$\)!\1$REPLRULE2\2!g"
	NRL="s!(Group.*)$ALTPKGNAME( |,|}|\$)!\1$TARGETPKGNAME\2!g"
	[ -n "$VERBOSE" ] && echo && echo "Use group name rule $NRL from $USEDPKGREPL"
	ALLGRPREPLRULES="$ALLGRPREPLRULES $NRL;"
done
echo
#echo GRP: $LISTGROUP, ALLGRPREPLRULES: $ALLGRPREPLRULES

# add %defattr to files sections
# FIXME: добавляет ненужные пустые строки
function awk_e1()
{
	[ -n "$ADDDEF" ] &&	awk 'BEGIN{desk=0}{print;if(/^%files/){printf("%s\n", text)}}' text="$ADDDEF" || cat
}

# add clean before %files
function awk_e2()
{
	[ -n "$CLEANTEXT" ] && awk 'BEGIN{desk=0}{if(/^%files/&&desk==0){printf("%s\n\n", text);desk++};print}' text="$CLEANTEXT" || cat
}

# add rpm-build-compat buildreq
function awk_e3()
{
	[ -n "$BUILDREQ" ] && awk 'BEGIN{desk=0}{if(/^%description/&&desk==0){printf("%s\n\n", text);desk++};print}' text="$BUILDREQ" || cat
}

# add commands in build section
function awk_section_build()
{
	[ -n "$ADDFIXCOMMAND" ] && awk 'BEGIN{desk=0}{print;if(/^%build/&&desk==0){printf("%s\n", text);desk++}}' text="$ADDFIXCOMMAND" || cat
}

# apply replacement rules
repl_reqs()
{
	local PREGE
	PREGE="perl -p -e"
	[ -n "$ALLREPLRULES" ] && $PREGE "$ALLREPLRULES" || cat
}

# apply replacement rules
repl_groups()
{
	local PREGE
	PREGE="perl -p -e"
	[ -n "$ALLGRPREPLRULES" ] && $PREGE "$ALLGRPREPLRULES" || cat
}

if [ -n "$VERBOSE" ] ; then
	echo "Replacing..."
fi

# apply all rules, awk excludes, remove empty tag lines
mv $SPECNAME $SPECNAME.old &&
	cat $SPECNAME.old | \
		repl_reqs | repl_groups | \
		awk_e1 | awk_e2 | awk_e3 | awk_section_build | \
		sed -e "s|^BuildRequires: *\$||g" | \
		sed -e "s|^BuildPreReq: *\$||g" | \
		sed -e "s|^Requires: *\$||g" | \
		sed -e "s|^Conflicts: *\$||g" | \
		sed -e "s|^Provides: *\$||g" | \
		sed -e "s|^Obsoletes: *\$||g" | \
		cat > $SPECNAME

# Some system does mismatch for Patch: and %patch0, Patch0: and %patch
subst "s|^Patch0:|Patch:|g" $SPECNAME
subst "s|^%patch0 |%patch |g" $SPECNAME

if [ "$PKGVENDOR" != "alt" ] ; then 
	# Due possible using %release in Source: and Patch: names
	subst "s|^\(Source.*\)%release|\1$RELEASE|g" $SPECNAME
	subst "s|^\(Patch.*\)%release|\1$RELEASE|g" $SPECNAME

	if ! grep -q "%setup *-q" $SPECNAME ; then
		subst "s|^%setup |%setup -q |g" $SPECNAME
		subst "s|^%setup$|%setup -q|g" $SPECNAME
	fi
	# obsoletes since Slackware/13 (rpm 4.10)
	subst "s|^BuildPreReq:|BuildRequires:|g" $SPECNAME
	subst "s|^PreReq:|Requires:|g" $SPECNAME

	# not supported anywhere exclude ALT
	subst "s|^BuildRequires(pre):|BuildRequires:|g" $SPECNAME
fi

if [ "$PKGVENDOR" != "alt" ] ; then
	# for systems with (d)ash as sh (f.i., Ubuntu)
	remove_bashism $SPECNAME
fi

#TODO:
#%if %{undefined buildroot}
#BuildRoot: %{_tmppath}/%{name}-%{version}-buildroot
#%endif

#TODO:
#%clean section

rm -f $SPECNAME.old

if [ "$PKGVENDOR" = "alt" ] ; then
	subst "1i#" $SPECNAME

	subst "1i# This spec is backported to $DISTRNAME $DISTRVERSION automatically by rpmbph script from etersoft-build-utils." $SPECNAME
	ENTRY="- backport to $DISTRNAME $DISTRVERSION (by rpmbph script)"
	# TODO: obsoleted
	#DISTRARG="-$MDISTR"
else
	subst "1i# This spec is autoported from ALT Linux Sisyphus to $DISTRNAME $DISTRVERSION automatically by rpmbph script from etersoft-build-utils." $SPECNAME
	ENTRY="- autoport to $DISTRNAME $DISTRVERSION (by rpmbph script)"
	export USE_VENDOR=$RPMVENDOR
	export USE_LEGACY_COMPRESSION=1
	#DISTRARG=""
fi

test -s "$SPECNAME" || fatal "something is wrong. $SPECNAME is empty after converting."

test -n "$TOCHANGELOG" && ENTRY=`echo -e "$ENTRY\n- $TOCHANGELOG"`
add_changelog $SPECNAME -e "$ENTRY"

