#
# spec specific functions.
#
################################################################
#
# Copyright (c) 1995-2014 SUSE Linux Products GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 or 3 as
# published by the Free Software Foundation.
#
# 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 (see the file COPYING); if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#
################################################################

recipe_setup_spec() {
    spec_setup_stages "$BUILD_RPM_BUILD_STAGE"
    TOPDIR=`chroot $BUILD_ROOT su -c "rpm --eval '%_topdir'" - $BUILD_USER`
    if test -z "$TOPDIR"; then
	cleanup_and_exit 1 "Error: TOPDIR empty"
    fi
    test "$DO_INIT_TOPDIR" = false || spec_init_topdir
    for i in BUILD RPMS/`uname -m` RPMS/i386 RPMS/noarch SOURCES SPECS SRPMS BUILDROOT OTHER ; do
	mkdir -p $BUILD_ROOT$TOPDIR/$i
    done
    chown -R "$ABUILD_UID:$ABUILD_GID" "$BUILD_ROOT$TOPDIR"
    mkdir -p $BUILD_ROOT$TOPDIR/SOURCES
    cp -p "$MYSRCDIR"/* $BUILD_ROOT$TOPDIR/SOURCES/
}

recipe_prepare_spec() {
    # fixup specfile
    args=()
    if test -n "$RELEASE" ; then
	args[${#args[@]}]="--release"
	args[${#args[@]}]="$RELEASE"
    fi
    if test -n "$BUILD_FLAVOR" ; then
	args[${#args[@]}]="--buildflavor"
	args[${#args[@]}]="$BUILD_FLAVOR"
    fi
    if test -n "$OBS_PACKAGE" ; then
	args[${#args[@]}]="--obspackage"
	args[${#args[@]}]="$OBS_PACKAGE"
    fi
    if test -n "$CHANGELOG" -a -f "$BUILD_ROOT/.build-changelog" ; then
	args[${#args[@]}]="--changelog"
	args[${#args[@]}]="$BUILD_ROOT/.build-changelog"
    fi

    substitutedeps "${args[@]}" --root "$BUILD_ROOT" --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" "$BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE" "$BUILD_ROOT/.spec.new" || cleanup_and_exit 1

    # fix rpmrc if we are compiling for i686
    test -f $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 && mv $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 $BUILD_ROOT/usr/lib/rpm/rpmrc
    if test -e $BUILD_ROOT/usr/lib/rpm/rpmrc -a "$BUILD_ARCH" != "${BUILD_ARCH#i686}" ; then
	mv $BUILD_ROOT/usr/lib/rpm/rpmrc $BUILD_ROOT/usr/lib/rpm/rpmrc_i586
	sed -e 's/^buildarchtranslate: athlon.*/buildarchtranslate: athlon: i686/' -e 's/^buildarchtranslate: i686.*/buildarchtranslate: i686: i686/' < $BUILD_ROOT/usr/lib/rpm/rpmrc_i586 > $BUILD_ROOT/usr/lib/rpm/rpmrc
    fi

    # extract macros from configuration
    rawcfgmacros=.rpmmacros
    test "$BUILDTYPE" = debbuild && rawcfgmacros=.debmacros
    queryconfig rawmacros --dist "$BUILD_DIST" --archpath "$BUILD_ARCH" --configdir "$CONFIG_DIR" > $BUILD_ROOT/root/$rawcfgmacros
    if test -n "$BUILD_DEBUG" && test "$BUILDTYPE" != debbuild ; then
	echo '
%prep %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%prep
%package %{?!__debug_package:%{?_build_create_debug:%?_build_insert_debug_package}}%%package
%_build_insert_debug_package \
%global __debug_package 1 \
%undefine _enable_debug_packages \
%debug_package

' >> $BUILD_ROOT/root/$rawcfgmacros
    fi

    if test -n "$BUILD_JOBS" ; then
	cat >> $BUILD_ROOT/root/$rawcfgmacros <<-EOF
		### from obs-build
		%jobs $BUILD_JOBS
		%_smp_mflags -j$BUILD_JOBS
		EOF
    fi
    test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/$rawcfgmacros $BUILD_ROOT/home/abuild/$rawcfgmacros

    # extract optflags from configuration
    queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" optflags ${BUILD_DEBUG:+debug} > $BUILD_ROOT/root/.rpmrc
    test $BUILD_USER = abuild && cp -p $BUILD_ROOT/root/.rpmrc $BUILD_ROOT/home/abuild/.rpmrc

    if test -z "$ABUILD_TARGET"; then
	ABUILD_TARGET=$(queryconfig target --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" )
	test -z "$ABUILD_TARGET" || echo "build target is $ABUILD_TARGET"
    fi

    # report specfile changes
    if test -f $BUILD_ROOT/.spec.new ; then
	if ! cmp -s $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE $BUILD_ROOT/.spec.new ; then
	    echo -----------------------------------------------------------------
	    echo "I have the following modifications for $RECIPEFILE:"
	    sed -e "/^%changelog/q" $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE > $BUILD_ROOT/.spec.t1
	    sed -e "/^%changelog/q" $BUILD_ROOT/.spec.new > $BUILD_ROOT/.spec.t2
	    diff $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
	    rm -f $BUILD_ROOT/.spec.t1 $BUILD_ROOT/.spec.t2
	    mv $BUILD_ROOT/.spec.new $BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE
	else
	    rm -f $BUILD_ROOT/.spec.new
	fi
    fi
}

spec_is_empty_dir() {
    local d
    for d in "$1"/* ; do
	test -e "$d" && return 1
    done
    return 0
}

spec_init_topdir() {
    local d keepbuild keepbuildroot
    case "${rpmstages[0]}" in
	-b[ci]\ --short-circuit) keepbuild=BUILD ;;
	-bb\ --short-circuit | -bl) keepbuild=BUILD keepbuildroot=BUILDROOT ;;
    esac
    if test -n "$keepbuild$keepbuildroot" ; then
	for d in $keepbuild $keepbuildroot ; do
	    spec_is_empty_dir "$BUILD_ROOT$TOPDIR/$d" && cleanup_and_exit 1 "need files in $TOPDIR/$d for '${rpmstages[0]}'"
	done
	for d in "$BUILD_ROOT$TOPDIR"/* "$BUILD_ROOT$TOPDIR"/.[^.]* ; do
	    test "$d" = "$BUILD_ROOT$TOPDIR/$keepbuild" -o "$d" = "$BUILD_ROOT$TOPDIR/$keepbuildroot" && continue
	    rm -rf "$d"
	done
    else
	rm -rf "$BUILD_ROOT$TOPDIR"
    fi
}

spec_setup_stages() {
    local stage="$1"
    test "$stage#-b[a-z]" != "$stage" && stage="${stage#-b}"        # compat
    local xstage=pciba
    case $stage in
	"")	     stage=pciba ;;
	[lr])        ;;
	[pciba])     stage="${xstage%$stage*}$stage" ;;
	[pcibalr]=)  stage="${stage%=}" ;;
	[pciba]+)    stage="${stage%+}${xstage#*${stage%+}}" ;;
	s+ | s= | s) stage=s ;;
	*)           cleanup_and_exit 1 "unknown stage '$stage'" ;;
    esac
    stage=${stage//s/a}
    rpmstages=()
    case $stage in
	p | pc | pci | pcib | pciba) rpmstages[${#rpmstages[@]}]="-b${stage: -1}" ; stage= ;;
    esac
    while test -n "$stage" ; do
	local opt="-b${stage:0:1}"
	case "${stage:0:1}" in
	    a)     opt="-bs" ;;
	    [cib]) opt="$opt --short-circuit" ;;
	esac
	rpmstages[${#rpmstages[@]}]="$opt"
	stage=${stage:1}
    done
}

recipe_build_spec() {
    rpmbuild=rpmbuild
    test -x $BUILD_ROOT/usr/bin/rpmbuild || rpmbuild=rpm
    test "$BUILDTYPE" = debbuild && rpmbuild=debbuild

    HAVE_DYNAMIC_BUILDREQUIRES=
    if egrep '^%generate_buildrequires' "$BUILD_ROOT$TOPDIR/SOURCES/$RECIPEFILE" >/dev/null ; then
	HAVE_DYNAMIC_BUILDREQUIRES=true
    fi

    # XXX: move _srcdefattr to macro file?
    rpmbopts=("--define" "_srcdefattr (-,root,root)")
    if test "$DO_CHECKS" != true ; then
	if chroot "$BUILD_ROOT" "$rpmbuild" --nocheck --help >/dev/null 2>&1; then
	    rpmbopts[${#rpmbopts[@]}]="--nocheck"
	else
	    echo "warning: --nocheck is not supported by this $rpmbuild version"
	fi
    fi
    if test "$rpmbuild" == "debbuild" ; then
	rpmbopts[${#rpmbopts[@]}]="-vv"
    fi
    if test "$rpmbuild" == "rpmbuild" ; then
	    # use only --nosignature for rpm v4
	rpmbopts[${#rpmbopts[@]}]="--nosignature"
    fi
    if test -n "$ABUILD_TARGET" ; then
	rpmbopts[${#rpmbopts[@]}]="--target=$ABUILD_TARGET"
    fi
    # sysroot packages are not in the database
    if test -n "$ABUILD_TARGET" -a -d "$BUILD_ROOT/.build.sysroot" ; then
	rpmbopts[${#rpmbopts[@]}]="--nocheck"
	rpmbopts[${#rpmbopts[@]}]="--nodeps"
    fi
    if test -n "$BUILD_DEBUG" ; then
	rpmbopts[${#rpmbopts[@]}]='--define'
	rpmbopts[${#rpmbopts[@]}]="_build_create_debug 1"
    fi
    if test -n "$DISTURL" ; then
	rpmbopts[${#rpmbopts[@]}]='--define'
	rpmbopts[${#rpmbopts[@]}]="disturl $DISTURL"
    fi
    if test -n "$RSYNCDONE" ; then
	rpmbopts[${#rpmbopts[@]}]='--define'
	rpmbopts[${#rpmbopts[@]}]="RSYNCDONE 1"
    fi

    buildrootoverride=$(queryconfig --dist "$BUILD_DIST" --configdir "$CONFIG_DIR" --archpath "$BUILD_ARCH" buildflags rpm-buildroot-override)
    if test -n "$buildrootoverride" ; then
	rpmbopts[${#rpmbopts[@]}]='--buildroot'
	rpmbopts[${#rpmbopts[@]}]="$buildrootoverride"
    fi

    GEN_BUILDREQS_PACKS=()
    if test -n "$HAVE_DYNAMIC_BUILDREQUIRES" ; then
	# query dynamic build requires
	rm -f "$BUILD_ROOT$TOPDIR/SRPMS/"*.buildreqs.nosrc.rpm
	toshellscript $rpmbuild \
		--nodeps \
		"${definesnstuff[@]}" \
		-br \
		"${rpmbopts[@]}" \
		"$TOPDIR/SOURCES/$RECIPEFILE" \
		> $BUILD_ROOT/.build.command
	chmod 755 $BUILD_ROOT/.build.command
	chroot $BUILD_ROOT su -c /.build.command - $BUILD_USER < /dev/null
	st=$?
	if test "$st" != 0 -a "$st" != 11 ; then
	    return
	fi
	: > $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs
	if test "$st" = 11 ; then
	    reqsfile=
	    for i in "$BUILD_ROOT$TOPDIR/SRPMS/"*.buildreqs.nosrc.rpm ; do
		test -f "$i" && reqsfile=${i##*/}
	    done
	    test -n "$reqsfile" || cleanup_and_exit 1 "no buildreqs.nosrc.rpm file?"
	    chroot $BUILD_ROOT rpm -qp --requires "$TOPDIR/SRPMS/$reqsfile" | grep -v '^rpmlib(' | sort -u > $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs_tmp
	    chroot $BUILD_ROOT rpmspec -q --srpm --requires "$TOPDIR/SOURCES/$RECIPEFILE" >> $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs_tmp || cleanup_and_exit 1 "rpm -q --spec failed"
	    sort < $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs_tmp | uniq -u > $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs
	    rm -f $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs_tmp
	    while read db ; do
		GEN_BUILDREQS_PACKS[${#GEN_BUILDREQS_PACKS[@]}]="$db"
	    done < $BUILD_ROOT$TOPDIR/OTHER/_generated_buildreqs
	fi
	rm -f "$BUILD_ROOT$TOPDIR/SRPMS/"*.buildreqs.nosrc.rpm
    fi

    for rpmstage in "${rpmstages[@]}" ; do
	# su involves a shell which would require even more
	# complicated quoting to bypass than this
	toshellscript $rpmbuild \
		"${definesnstuff[@]}" \
		$rpmstage \
		"${rpmbopts[@]}" \
		"$TOPDIR/SOURCES/$RECIPEFILE" \
		> $BUILD_ROOT/.build.command
	chmod 755 $BUILD_ROOT/.build.command
	check_exit
	chroot $BUILD_ROOT su -c /.build.command - $BUILD_USER < /dev/null
	st=$?
	test "$st" = 0 || break
    done
    test "$st" = 0 && BUILD_SUCCEEDED=true
    test "$st" = 11 -a -n "$HAVE_DYNAMIC_BUILDREQUIRES" && BUILD_SUCCEEDED=genbuildreqs
}

recipe_resultdirs_spec() {
    echo RPMS SRPMS
}

recipe_cleanup_spec() {
    :
}

recipe_unpack_srcrpm() {
    test -n "$LIST_STATE" || echo "processing src rpm $SRCDIR/$RECIPEFILE ..."
    MYSRCDIR="$BUILD_ROOT/.build-srcdir"
    rm -rf "$MYSRCDIR"
    mkdir -p "$MYSRCDIR"
    cd $MYSRCDIR || cleanup_and_exit 1
    $BUILD_DIR/unrpm -q $SRCDIR/$RECIPEFILE || {
	cleanup_and_exit 1 "could not unpack $RECIPEFILE."
    }
    for RECIPEFILE in *.spec ; do : ; done
}

# post build functions... move somewhere else?

recipe_check_file_owners() {
    echo "... checking for files with abuild user/group"
    BADFILE=
    while read un gn fn ; do
        if test "$un" = abuild -o "$gn" = abuild -o "$un" = ${ABUILD_UID} -o "$gn" = ${ABUILD_GID} ; then
            echo "  $un $gn $fn"
            BADFILE=true
        fi
    done < <(rpm -qp --qf '[%{FILEUSERNAME} %{FILEGROUPNAME} %{FILENAMES}\n]' $RPMS)
    if test -n "$BADFILE" ; then
        cleanup_and_exit 1 "please fix your filelist (e.g. add defattr)"
    fi
}

recipe_run_rpmlint() {
    # SUSE builds are using a special rpmlint binary which is not
    # pulling in additional dependencies
    local rpmlint="/opt/testing/bin/rpmlint"
    if ! test -x "$BUILD_ROOT$rpmlint" ; then
        # default rpmlint place as fallback
        rpmlint="/usr/bin/rpmlint"
    fi
    if ! test -x "$BUILD_ROOT$rpmlint" ; then
	return
    fi
    LINT_RPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/RPMS \
	\( -name "*-debuginfo-*" -o -name "*-debugsource-*" \
	-o -name "*-32bit-*" -o -name "*-64bit-*" \
	-o -name "*-x86-*" -o -name "*-ia32-*" \) -prune \
	-o -type f -name '*.rpm' -print))
    SRPM_FILE_LIST=($(find $BUILD_ROOT/$TOPDIR/SRPMS -type f -name "*.rpm"))
    echo 
    echo "RPMLINT report:"
    echo "==============="
    rpmlint_logfile=$TOPDIR/OTHER/rpmlint.log
    rm -f "$BUILD_ROOT$rpmlint_logfile"
    ret=0
    chroot $BUILD_ROOT su -s $rpmlint "$BUILD_USER" -- \
	    --info ${LINT_RPM_FILE_LIST[*]#$BUILD_ROOT} \
	    ${SRPM_FILE_LIST[*]#$BUILD_ROOT} > >(tee "$BUILD_ROOT$rpmlint_logfile") 2>&1 || ret=1
    echo
    if test "$ret" = 1 ; then 
	cleanup_and_exit 1
    fi   
}

recipe_compare_oldpackages() {
    if test -x "$BUILD_ROOT/usr/lib/build/same-build-result.sh" ; then 
	echo "... comparing built packages with the former built"
	if chroot $BUILD_ROOT /usr/lib/build/same-build-result.sh /.build.oldpackages "$TOPDIR/RPMS" "$TOPDIR/SRPMS"; then 
	    chroot $BUILD_ROOT touch /.build/.same_result_marker
	    # XXX: dirty build service hack. fix bs_worker. Search for
	    # 'same_result_marker' for traces of a first try to get rid of this
	    if test -n "$REASON" -a -n "$DISTURL" ; then 
		exitcode=2
	    fi
	fi
    fi   
}

recipe_create_deltarpms() {
    if test -x "$BUILD_ROOT/usr/bin/makedeltarpm" -a -x $BUILD_ROOT/usr/lib/build/mkdrpms ; then
	echo "... creating delta rpms"
	ds=("$BUILD_ROOT/$TOPDIR"/RPMS/* "$BUILD_ROOT$TOPDIR/SRPMS")
	chroot $BUILD_ROOT /usr/lib/build/mkdrpms /.build.oldpackages "${ds[@]#$BUILD_ROOT}"
    fi
}

