#!/bin/sh
#
#upgradedb: version 1.0
#
#a script to upgrade a tgz and retrive tgz dependency list.
#
#usage:
#
#./upgradedb option [oldpackagename%]newpackagename
#
#where:
#option is:
#	--install-new
#	--reinstall
#	--nooption (actually anything different from the two above)
#oldpackagename is the name of the tgz package inside the slack database
#newpackagename is the name of the tgz package used to upgrade


#--------------------------------------------------------------
#aux. functions - useful stuff for the tracing of dependencies

. $INSTDIR/core-functions


function splitArg ()
#split the arg filling the OLDPKG and the NEWPKG values
{
OLDPKG=`echo $1 | cut -f1 -d %`
FILE=`echo $1 | cut -f2 -d %` #FILE is an extern variable
}


function retriveOldPkg ()
#retrive the old package name from the new package name, filling the OLDPKG value
#the file name is assumed to be in the standard form:
#name-version-arch-build.tgz
#we need just the 'name' field which is composed, in its turn, of one or more fields
#(e.g. glibc-solibs are 2 fields)
{
#retrive package name
POLDPKG=`echo $1 | awk -F - '{for (i=1; i<NF-3; i++) {printf $i"-"}; printf $(NF-3)}'`

#retrive complete package string
#if the package is not installed we obtain a void string: OLDPKG=""
#if more packages match the "$OLDPKG" expression we have to find the right one
#(e.g. if we grep "gimp" we can retrieve both:
# 1-  gimp-version-arch-build
# and
# 2- gimp-print-version-arch-build
# packages)
TMPPKG=`ls $PKGDIR | grep -w "$POLDPKG" -`
for FILE_ in $TMPPKG; do
	#retrieve package name
	FILENAME=`echo $FILE_ | awk -F - '{for (i=1; i<NF-3; i++) {printf $i"-"}; printf $(NF-3)}'`
	#find the _RIGHT_ package and exit
	[ "$FILENAME" = "$POLDPKG" ] && { OLDPKG="$FILE_"; break; }
done
}


function findNew ()
#define if a given tgz is an upgrade or is new (= there isn't any previous version installed)
#$1 is the name of the old package already installed (if not found, $1="")
#$2 is the name of the new package we want to install via 'tracepkg --install-new'
{
if [ "$1" = "" ]; then
	INSTALLNEW[$j]=$2
	(( j++ ))
else
	UPGRADE[$k]=$2
	UPGRADED[$k]=$1
	(( k++ ))
fi
}
#--------------------------------------------------------------


#--------------------------------------------------------------
#main section

OPTION=$1;
shift 1;

case $OPTION in
	"--reinstall") UPGRADEPKG="upgradepkg --reinstall" ;;
	"--install-new") UPGRADEPKG="upgradepkg --install-new" ;;
	*) UPGRADEPKG="upgradepkg" ;;
esac

#following values and arrays are modified by function 'findNew'
j=0;
k=0;
INSTALLNEW[$j]=""
UPGRADE[$k]=""
UPGRADED[$k]=""

#we collect new tgz's and upgradeable tgz's in separate arrays
for FILE in $@; do
	OLDPKG=""

	#have a look to the arg
	echo $FILE | grep % > /dev/null
	if [ $? -eq 0 ]; then
		splitArg $FILE
	else
	#discover old package...
	#assume that the passed arg is the new package
		NEWPKG=`basename $FILE .tgz`
		retriveOldPkg $NEWPKG
	fi
	findNew "$OLDPKG" $FILE
done

USINGLIST=""

h=0;
[ ! $j -eq 0 ] && {
if [ "$OPTION" = "--install-new" ]; then
	for ((y=0; y<$j; y++)); do
		#let me explain the following lines:
		#
		#	if we fail the upgrade (return a value=0) or if we have a 'noarch' tgz,
		#	we set the value to a void string:
		#	when we'll pass all the array to the 'updateData' function at the end
		#	of the script, all void lines into the arglist will not be expanded by the function,
		#	avoiding dependency check when it is not required.
		#
		$UPGRADEPKG ${INSTALLNEW[$y]}
		if [ $? -eq 0 ]; then
			noarchTest ${INSTALLNEW[$y]};
			if [ $? -eq 0 ]; then
				INSTALLNEW[$y]=$PKGDIR/`basename ${INSTALLNEW[$y]} .tgz`
				USINGLIST=(${USINGLIST[@]} ${INSTALLNEW[$y]})
				(( h++ ))
			else
			#if we pass the upgrade but we have a 'noarch' tgz
				INSTALLNEW[$y]=""
			fi
		else
		#if we fail the upgrade
			INSTALLNEW[$y]=""
		fi
	done
else
	echo -e "* no file found for upgrade, use '--install' or '--install-new' options with the following tgz's:\n${INSTALLNEW[@]}\notherwise, try the extended form: --upgrade oldpackagename%newpackagename"
fi
}

for ((i=0; i<$k; i++)); do
#upgrade already installed tgz's
	NEWPKG=`basename ${UPGRADE[$i]} .tgz`
	OLDPKG=`basename ${UPGRADED[$i]} .tgz`

	if [ "$OLDPKG" = "$NEWPKG" ]; then
	#if we have the same version
		if [ ! "$OPTION" = "--reinstall" ]; then
			echo "  --> new: $OLDPKG"
			echo "  --> installed: $NEWPKG"
			echo -e "* package versions match. upgrade is not required"
		else
		#we reinstall the tgz without rebuild the database:
		#usually the --reinstall option	is usefull if a tgz has been damaged
			$UPGRADEPKG ${UPGRADE[$i]}
		fi
		continue;
	fi

	noarchTest $OLDPKG
	[ $? -eq 1 ] && {
		#check for "noarch" package: if we have a noarch tgz we don't need anything else than
		#upgrade the package
		$UPGRADEPKG "${UPGRADED[$i]}%${UPGRADE[$i]}"
		continue;
	}

#have a look for packages that use the tgz we want to upgrade
	PKGUSEDBY=(`checkList $PKGDIR/$OLDPKG`)
	USING=${#PKGUSEDBY[@]};

	[ ! $USING -eq 0 ] && {
		hilightDependant $OLDPKG ${PKGUSEDBY[@]}
		echo -e "PACKAGE NAME:\n$OLDPKG\n"
		YES_NO="";
		[ $AUTO -eq 0 ] && {
			ask_yesno "is _IN USE_ by other packages, would you like to upgrade it [yes/no]? "
		} || {
			YES_NO="yes"
		}
		[ "$YES_NO" = "no" ] && continue
	}

	#upgrade the package
	$UPGRADEPKG "${UPGRADED[$i]}%${UPGRADE[$i]}"
	[ $? -eq 0 ] && {
		#if no problem occurred...
		#we store tgz's dependant on the given tgz (if they exist)
		[ ! $USING -eq 0 ] && USINGLIST=(${USINGLIST[@]} ${PKGUSEDBY[@]});
	 	#remove dependency file lists for old package
		removedep $OLDPKG

		#store new file name
		USINGLIST=(${USINGLIST[@]} "$PKGDIR/$NEWPKG")
	}

done

#we need to update dependency list for: -new & upgraded tgz's;
#					-old tgz's dependant on new tgz's.
echo -e "\nupdating data"

[ ! "${USINGLIST[0]}" = "" ] && rebuildData ${USINGLIST[@]}

[ ! $h -eq 0 ] && [ "$OPTION" = "--install-new" ] && {
	updateData ${INSTALLNEW[@]}
}


echo "...done"
#--------------------------------------------------------------

#EOF
