#!/bin/bash

test "$1" = "--verbose" && { VERBOSE=true ; shift ; }
test "$1" = "--batchmode" && { BATCHMODE=true ; shift ; }
DIR_TO_CHECK=$1
DESTINATIONDIR=$2
OSC_MODE=""
test -n "$DIR_TO_CHECK" || DIR_TO_CHECK=`pwd`
test -z "$DESTINATIONDIR" -a -d "$DIR_TO_CHECK/.osc" && {
	DESTINATIONDIR="$DIR_TO_CHECK/.osc"
	OSC_MODE="true"
}


RETURN=0
RPMBUILD=rpm
test -x /usr/bin/rpmbuild && RPMBUILD=rpmbuild

#
#  cleanup_and_exit
#
cleanup_and_exit () {
    rm -rf $TMPDIR
    exit $1
}

test "$VERBOSE" = true && echo -n "- checking if needed files are present and none stale "
#
# first make my TMPDIR
#
export TMPDIR=`mktemp -d -t check_if_valid_source_dir-XXXXXX 2>/dev/null || mktemp -d /var/tmp/check_if_valid_source_dir-XXXXXX`
#
# now create list of Sources.
#
MY_ARCH=`uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/`
case $MY_ARCH in
  i386)
    MY_ARCH="%ix86"
    ;;
esac
for i in $DIR_TO_CHECK/*.spec ; do
        test -f $i || continue
	sed	'/^#%([^)]*$/,/^[^(]*)/d
		/^#[^%]/d
		/^#%(.*)/d
		/^%.*%(echo.*)/{;p;d;}
		/^%.*%([^)]*)/{
			s@%([^)]*)@1@
		}
		/^%define/{
			s@%(rpm -q.*)@1@
		}
		/^%define/{;p;d;}
		/^%nil/{;p;d;}
		/^%{nil}/{;p;d;}
		/^%global.*%(.*)/d
		/^%global/{;p;d;}
		/^%include/d
		/^%[a-z]*_requires/d
		/^%{[a-z]*_requires}/d
		/^%gconf_schemas_prereq/d
		/^%requires_eq/{;p;d;}
		/^%requires_ge/{;p;d;}
		/^%ifarch/{ 
                        s@.*@%ifarch '$MY_ARCH'@
                }
		/^ExcludeArch:/d
		/^%error/d
		/^ExclusiveArch:/{
			s@.*@ExclusiveArch: '$MY_ARCH'@
		}
		/^BuildArch.*:/{
			s@.*@BuildArch: '$MY_ARCH'@
		}
		/^%if.*%{name}/{;p;d;}
		/^%if[^a]/{ 
                        s@.*@%if 1@
                }
		/^%if/{;p;d;}
		/^%{\!/{;p;d;}
		/^%{?/{;p;d;}
		/^%{expand/d
		/^%error/{;p;d;}
		/^%else/{
			s@.*@%endif\n%if 1@
		}
		/^%(.*)/{;d;}
		/^%end/{;p;d;}
		/^%bcond/{;p;d;}
		/^%{py/{;p;d;}
		/^%py_r/{;p;d;}
		/^%/{;s/.*//;q;}
		/^Requires:/d
		/^Requires(.*):/d
		/^No[Ss]ource/d
		/^NoPatch/d
		/^BuildPrereq/d
		/^Build[Rr]equires/d
		/^Pre[Rr]eq/d
		/^Icon/d
		/^Recommends/d
		/^Supplements/d
		/^Suggests/d
		/^Enhances/d
		/^\([Ss]ource\|[Pp]atch\)[0-9]*:[ 	]*/{
			s/^\(\([Ss]ource\|[Pp]atch\)[0-9]*:[ 	]*\)\(.*\)/##seen \1\3\n%{echo:\3 }/
		}
		s/^Release:.*<RELEASE.*>/Release: 0/' $i >$TMPDIR/tmp.spec
	grep -a ^Icon: $i|sed -n 's/^Icon:[ 	]*/%{echo:/
		/^%{echo:/s/$/ }/p' >>$TMPDIR/tmp.spec
	grep -a -q ^Release $i || {
             sed -e "/^Version/{;p;s@\(.*\)@Release: 0\
@;}" $TMPDIR/tmp.spec > $TMPDIR/tmp.spec.new
	     mv $TMPDIR/tmp.spec.new $TMPDIR/tmp.spec
	}
	while test `grep -a "^%if" $TMPDIR/tmp.spec | wc -l` \
		   -gt `grep -a "^%endif" $TMPDIR/tmp.spec | wc -l` ; do
		echo "%endif" >> $TMPDIR/tmp.spec
	done
	while read line ; do
	    grep -qx "##seen $line" $TMPDIR/tmp.spec || echo "$line" | sed -e "s/^\(\([Ss]ource\|[Pp]atch\)[0-9]*:[    ]*\)\(.*\)/##seen \1\3\n%{echo:\3 }/" >> $TMPDIR/tmp.spec
	done < <(grep -E "^Source:|^Source[0-9]*:|^Patch:|^Patch[0-9]*:" $i)
        echo "%description" >> $TMPDIR/tmp.spec

        # hack for really strange specfiles with more than one Name:/Release:/Version: line
        for nodup in Name Version Release ; do
            sed -e "s@^$nodup:@X$nodup:@" -e "0,/^X$nodup:/{s@^X$nodup:@$nodup:@}" -e "s@^X$nodup:.*@@" $TMPDIR/tmp.spec > $TMPDIR/tmp.spec.2 && mv $TMPDIR/tmp.spec.2 $TMPDIR/tmp.spec
        done

	$RPMBUILD --nodeps -bp $TMPDIR/tmp.spec >> $TMPDIR/sources 2>&1 || {
	    $RPMBUILD --nodeps -bp $TMPDIR/tmp.spec
	    cleanup_and_exit 1
	}
	egrep -v '^warning' $TMPDIR/sources > $TMPDIR/sources.t && mv $TMPDIR/sources.t $TMPDIR/sources
done

test -f $TMPDIR/sources || cleanup_and_exit

#
# check if all Sources, patches and the icon are present
#
touch $TMPDIR/sources.t
grep -aq "command not found" $TMPDIR/sources && {
	echo "$0 seems to have problems evaluating macros in specfile."
	COMD=`grep -a "command not found" $TMPDIR/sources | head -n 1 | sed -e "s@.*: \([^:]*\): command not found@\1@"`
	echo "command \"$COMD\" is not available used in the following defines:"
	grep -a "%define.*$COMD" $DIR_TO_CHECK/*.spec
	cleanup_and_exit 1
}

for i in `cat $TMPDIR/sources` ; do
	echo "${i##*/}" >> $TMPDIR/sources.t
done
mv $TMPDIR/sources.t $TMPDIR/sources

check_tracked()
{
	local file=${1##*/}

	if ! test -f "$DIR_TO_CHECK/$file"; then
		echo "(E) $file mentioned in spec file does not exist."
		return 1
	fi
	if test "$OSC_MODE" = "true" ; then
		if test -f "$DESTINATIONDIR/$file"; then
			return 0
		fi
		if grep -qsFx "$file" "$DESTINATIONDIR/_to_be_added"; then
			return 0
		fi
		echo "(E) $file mentioned in spec file is not tracked."
		return 1
	fi
}

for HASTOBETHER in `cat $TMPDIR/sources` ; do
    check_tracked "$HASTOBETHER" || RETURN=2
done

#
# Skip this test for now, if we have server side downloads
#
if [ -e $DIR_TO_CHECK/_service ]; then
    exit 0
fi

#
# now check if everything is marked in spec files.
#
for i in $DIR_TO_CHECK/* $DIR_TO_CHECK/.* ; do
    BASE=${i##*/}
    case $BASE in
	\.|\.\.) continue ;;
    esac
    # files to display first
    case $BASE in 
	config-dist.sh | \
	get_version_number.sh | \
	get_release_number.sh | \
	check-build.sh | \
	baselibs.conf )
	    if test -n "$DESTINATIONDIR" -a -f "$DESTINATIONDIR/$BASE" && cmp -s "$DIR_TO_CHECK/$BASE" "$DESTINATIONDIR/$BASE" ; then
		echo "- package has $BASE: (unchanged)"
	    else
		echo "- package has $BASE: (new or modified)"
		echo "--------------------------------------------------------------"
		cat $DIR_TO_CHECK/$BASE
		echo "--------------------------------------------------------------"
		if test "$BATCHMODE" != true ; then
		    echo -n "Is this correct? [N/y/d] (y to ignore) "
		    read ANSWER
		    test "$ANSWER" = y -o "$ANSWER" = Y || {
			if test "$ANSWER" = d -o "$ANSWER" = D ; then
			    rm -v $DIR_TO_CHECK/$BASE
			else
			    echo ok, please fix it...
			    test "$RETURN" != "2" && RETURN=1
			fi
		    }
	    	else
		    echo "###ASK $DIR_TO_CHECK/$BASE"
	    	fi
	    fi
	    ;;
	*rpmlintrc)
	    if test -n "$DESTINATIONDIR" -a -f "$DESTINATIONDIR/$BASE" && cmp -s "$DIR_TO_CHECK/$BASE" "$DESTINATIONDIR/$BASE" ; then
		echo "- package has $BASE: (unchanged)"
	    else
		echo "- package has $BASE: (new or modified)"
		echo "--------------------------------------------------------------"
		cat $DIR_TO_CHECK/$BASE
		echo "--------------------------------------------------------------"
		if test "$BATCHMODE" != true ; then
		    echo -n "Is this correct? [N/y/d] (y to ignore) "
		    read ANSWER
		    test "$ANSWER" = y -o "$ANSWER" = Y || {
			if test "$ANSWER" = d -o "$ANSWER" = D ; then
			    rm -v $DIR_TO_CHECK/$BASE
			else
			    echo ok, please fix it...
			    test "$RETURN" != "2" && RETURN=1
			fi
		    }
		else
			echo "###ASK $DIR_TO_CHECK/$BASE"
		fi
	    fi

	    LINE=$(egrep "^[^#]*setBadness" "$DIR_TO_CHECK/$BASE")
	    if [ "$LINE" != "" ]; then
	        if test "$BATCHMODE" != true ; then
		    echo "ERROR: Found possibly illegal rpmlintrc line:"
		    echo "       $LINE"
		    echo -n "Is this correct? [N/y] (y to ignore) "
		    read ANSWER
		    test "$ANSWER" = y -o "$ANSWER" = Y || {
			echo ok, please fix it...
			test "$RETURN" != "2" && RETURN=1
		    }
		else
		    echo "###ASK $DIR_TO_CHECK/$BASE"
		fi
	    fi
	    ;;
	.*.spec)
	    rm -v $DIR_TO_CHECK/$BASE
	    ;; 
	*.changes | \
	*.lsm | \
	*.spec | \
	*.spec.in | \
	*.changes.in | \
	*.test | \
	MD5SUMS | \
	MD5SUMS.meta | \
	Makefile | \
	README.autobuild | \
	bigpack | \
	prepare-build.sh | \
	minmem | \
	needed_space_in_mb | \
	pre_checkin.sh | \
	newestfile | \
	.osc | \
	.bsinfo | \
	.bsnote | \
	.check_if_valid_source_dir | \
	.setup | \
	*.dsc | \
	ready | \
	_* | \
	*.orig | \
	*~ | \
	.git | \
	.gitignore | \
	.emacs.backup | \
	debian.changelog | \
	debian.compat | \
	debian.control | \
	debian.copyright | \
	debian.postinst | \
	debian.postrm | \
	debian.preinst | \
	debian.prerm | \
	debian.rules | \
	debian.tar.gz | \
	debian.triggers | \
	debian.*.default | \
	debian.*.dirs | \
	debian.*.files | \
	debian.*.init | \
	debian.*.install | \
	debian.*.logrotate | \
	debian.*.postinst | \
	debian.*.postrm | \
	debian.*.preinst | \
	debian.*.prerm )
	    ;;
	*)
	    grep -a -x $BASE $TMPDIR/sources > /dev/null && continue
	    echo "(W) Attention, $BASE is not mentioned in spec files as source or patch."
	    if test "$RETURN" != "2" ; then
	      if [ -d $DIR_TO_CHECK/$BASE ] ; then
                # be a bit more relaxed for osc, it won't upload directories anyway
                if [ ! -d $DIR_TO_CHECK/.osc ] ; then
		echo "!! $BASE is a directory !!"
		    if test "$BATCHMODE" != true ; then
		        echo    "     remove subtree with 'r'"
		        echo    "ignore and continue with 'y'"
		        echo -n "Is this correct? [N/y/r] "
		        read ANSWER
		        test "$ANSWER" = y -o "$ANSWER" = Y || {
			# r for remove is also accepted, to make it compatible with osc itself
		    	if test "$ANSWER" = d -o "$ANSWER" = D -o "$ANSWER" = r -o "$ANSWER" = R; then
		    	    rm -Rfv $DIR_TO_CHECK/$BASE
		    	else
		    	    echo ok, please fix it...
			    test "$RETURN" != "2" && RETURN=1
		    	fi
		        }
		    else
		        echo "###ASK -r $DIR_TO_CHECK/$BASE"
		    fi
		fi
	      else
		if test "$BATCHMODE" != true ; then
		    echo -n "Is this correct? [N/y/d] (y to ignore) "
		    read ANSWER
		    test "$ANSWER" = y -o "$ANSWER" = Y || {
			if test "$ANSWER" = d -o "$ANSWER" = D ; then
			    rm -v $DIR_TO_CHECK/$BASE
			else
			    echo ok, please fix it...
			    test "$RETURN" != "2" && RETURN=1
			fi
		    }
		else
		    echo "###ASK $DIR_TO_CHECK/$BASE"
		fi
	      fi
	    fi
	    ;;
    esac
done

test "$VERBOSE" = true && echo done

cleanup_and_exit $RETURN
