#!/bin/bash
# pacmanDeps - by Spider.007, based on an idea by skoal
# lists all dependencies of a package in a treeview

# This program may be freely redistributed under
# the terms of the GNU General Public License

_version="0.3b"
leafBranch='\033[30m|   \033[0m'
leafBranchParent='    '
leafPre='+---\033[1m'
leafPost='\033[0m'

# Query pacman and store dependencies in cache
_getDependencies () {
	local packageName=$1
	cacheEntry="deps_`echo $packageName|sed 's/[^a-zA-Z0-9]/_/g'`"
	local dependencies=

	# Try to cache results; only query pacman if cache isn't found
	if [ "`set|grep "^$cacheEntry="|wc -l`" = "0" ]
	then
		local packagePath=`find /var/lib/pacman/local/ -type d -name $packageName-* -print -quit`
		if [ ! -z "$packagePath" ]
		then
			local flag=0
			for line in `cat $packagePath/depends`
			do
				if [ "$flag" = "1" ]
				then
					[[ "$line" = "%REQUIREDBY%" ]] && break
					[[ "$flag" = "1" ]] && dependencies="$dependencies $line"
				fi
				[[ "$line" = "%DEPENDS%" ]] && flag=1
			done

		else
			dependencies=`pacman -Qs "$packageName"|sed '1!d;s/\(^.*\/\)\(.*\)\( .*$\)/\2/'`
		fi

		[[ "${dependencies}" = 'None' ]] && dependencies=
		eval $cacheEntry=\"$dependencies\"
	fi
}

# Visualize a dependency recursively
_showTree () {
	local packagePath=$1
	local leafDepth=$2
	local packageName=${packagePath##*\.}

	[[ -z "$leafDepth" ]] && leafDepth=0
	[[ -z "$parentLeaf" ]] && parentLeaf=0
	if [ $packageName = '_TOP_' ]
	then
		leafDepth=$(($leafDepth-1))
		unset packagePath
	else
		_showLeaf $packageName $leafDepth
	fi

	_getDependencies $packageName

#echo -e "\t\t$pPackagePath | $packagePath">&2
#echo "${pPackagePath/$packagePath/|    }"

	for dependency in `eval 'echo "$'"$cacheEntry"'"'`
	do
		if [ "${packagePath/.$packageName./}" != "${packagePath}" ]
		then
#			formattedPath=${packagePath#_TOP_.}
			formattedPath=${packagePath//./ > }
			echo -e "\033[1;31mLOOP: ${formattedPath}\033[m" >&2
			return
		else
			_showTree ${packagePath}.${dependency} $(($leafDepth+1))
		fi
	done

	pPackagePath=$packagePath
}

# Visualize a leaf of the tree
_showLeaf () {
	local packageName=$1
	local leafDepth=$2

	local leafCounter=$leafDepth
	while [ "${leafCounter}" -gt "1" ]
	do
		echo -ne "${leafBranchParent}"
		leafCounter=$(($leafCounter-1))
	done
	[[ "$leafleafCounter" -gt 1 ]] && echo -ne ${leafBranch}

	[[ "$leafDepth" -gt 0 ]] && echo -ne ${leafPre}
	echo -n ${packageName}
	[[ "$leafDepth" -gt 0 ]] && echo -ne ${leafPost}
	echo
}

# If no argument is given, use all packages as topnode
if [ $# -eq 0 ]
then
	deps__TOP_=`pacman -Qi|sed 's/ .*//'`
else
	if `pacman -Qi $*&>/dev/null`
	then
		deps__TOP_="$*"
	else
		echo Package \"$*\" was not found.
		exit 2
	fi
fi

_showTree '_TOP_'

exit 0

