# -*- mode: shell-script; sh-basic-offset: 8; indent-tabs-mode: t -*-
# ex: ts=8 sw=8 noet filetype=sh

have rpm && {
# helper functions for rpm completion
#
_rpm_installed_packages()
{
	local nodig="$1" nosig="$2"

	# if rpm (4.4.7+) is configured to export it's rpmdb to /var/cache/hrmib (%_hrmib_path)
	if [ -d /var/cache/hrmib -a -r /var/cache/hrmib ]; then
		COMPREPLY=( $( LC_ALL=C command ls -1 /var/cache/hrmib | sed -ne '/^'$cur'/p') )
		return
	fi

	# refresh cache if writable. FHS location
	if [ -w /var/cache/rpmpkgs.txt -a /var/cache/rpmpkgs.txt -ot /var/lib/rpm/Packages ]; then
		# we grab the output to local variable to prevent possible race
		_rpm_nodigsig
		local tmp=$(rpm -qa $nodig $nosig --qf '%{name}-%{version}-%{release}.%{arch}.rpm\n')
		echo "$tmp" > /var/cache/rpmpkgs.txt
	fi

	if [ -r /var/log/rpmpkgs -a \
		/var/log/rpmpkgs -nt /var/lib/rpm/Packages ]; then
		# using RHL 7.2 or later - this is quicker than querying the DB
		COMPREPLY=( $( sed -ne \
 		's|^\('$cur'.*\)\.rpm$|\1|p' \
				/var/log/rpmpkgs ) )
	else
		_rpm_nodigsig
		COMPREPLY=( $( rpm -qa $nodig $nosig --qf '%{name}-%{version}-%{release}.%{arch}\n' "$cur*" ) )
	fi
}

_rpm_groups()
{
	# TODO: shown completions are wrong but real ones work nevertheless
	# http://lists.alioth.debian.org/pipermail/bash-completion-devel/2009-May/001486.html
	local IFS=$'\n'
	COMPREPLY=( $( compgen -W "$( rpm -qa $nodig $nosig --queryformat \
		'%{group}\n' )" -- $cur ) )
}

_rpm_nodigsig()
{
	if [ -z "$nodig" -a -z "$nosig" ]; then
		local rpmver
	
		rpmver=$(rpm --version)
		rpmver=${rpmver##* }

		if [[ "$rpmver" > "4.0.4" ]]; then
			nodig="--nodigest"
		fi
		if [[ "$rpmver" > "4.0.99" ]]; then
			nosig="--nosignature"
		fi
	fi
}

# rpm(8) completion
#
_rpm()
{
	local cur prev nodig nosig

	COMPREPLY=()
	cur=`_get_cword`
	prev=${COMP_WORDS[COMP_CWORD-1]}
	nodig=""
	nosig=""
	_rpm_nodigsig

	if [ $COMP_CWORD -eq 1 ]; then
		# first parameter on line
		case "$cur" in
		-b*)
			COMPREPLY=( $( compgen -W '-ba -bb -bc -bi -bl -bp -bs'\
				       -- $cur ) )
			;;
		-t*)
			COMPREPLY=( $( compgen -W '-ta -tb -tc -ti -tl -tp -ts'\
				       -- $cur ) )
			;;
		--*)
			COMPREPLY=( $( compgen -W '--help --version --initdb \
			--checksig --recompile --rebuild --resign --addsign \
			--rebuilddb --showrc --setperms --setugids --tarbuild \
			--eval --install --upgrade --query --freshen --erase \
			--verify --querytags --rmsource --rmspec --clean \
			--import' -- $cur ) )
			;;
		*)
			COMPREPLY=( $( compgen -W '-b -e -E -F -i -q -t -U -V' \
				       -- $cur ) )
			;;
		esac

	return 0
	fi

	case "$prev" in
	--@(@(db|exclude)path|prefix|relocate|root))
		_filedir -d
		return 0
		;;
	--eval|-E)
		# get a list of macros
		COMPREPLY=( $( rpm --showrc | sed -ne \
		's/^-\?[0-9]\+[:=][[:space:]]\+\('${cur#%}'[^[:space:](]*\).*/\1/p' ) )
		COMPREPLY=( "${COMPREPLY[@]/#/%}" )
		return 0
		;;
	--pipe)
		COMPREPLY=( $( compgen -c -- $cur ) )
		return 0
		;;
	--rcfile)
		_filedir
		return 0
		;;
	--specfile)
		# complete on .spec files
		_filedir spec
		return 0
		;;
	--whatprovides)
		if [[ "$cur" == */* ]]; then
			_filedir
		else
			# complete on capabilities
			local IFS=$'\n'
			COMPREPLY=( $( compgen -W "$( rpm -qa $nodig $nosig \
					--queryformat='%{providename}\n' )" \
					-- $cur ) )
		fi
		return 0
		;;
	--whatrequires)
		if [[ "$cur" == */* ]]; then
			_filedir
		else
			# complete on capabilities
			local IFS=$'\n'
			COMPREPLY=( $( compgen -W "$( rpm -qa $nodig $nosig \
					--queryformat='%{requirename}\n' )" \
					-- $cur ) )
		fi
		return 0
		;;
	--target)
		COMPREPLY=( $( compgen -W "$( command rpm --showrc | sed -ne \
		's/^\s*compatible\s\+build\s\+archs\s*:\s*\(.*\)/\1/ p' )" -- $cur ) )
		return 0
		;;
	esac

	case "${COMP_WORDS[1]}" in
	-@([iFU]*|-install|-freshen|-upgrade))
		if [[ "$cur" == -* ]]; then
			COMPREPLY=( $( compgen -W '--percent --force --test \
			--replacepkgs --replacefiles --root --excludedocs \
			--includedocs --noscripts --rcfile --ignorearch \
			--dbpath --prefix --ignoreos --nodeps --allfiles \
			--ftpproxy --ftpport --justdb --httpproxy --httpport \
			--noorder --relocate --badreloc --notriggers \
			--excludepath --ignoresize --oldpackage --define \
			--eval --pipe --queryformat --repackage --nosuggests \
			--nodigest --nosignature' -- $cur ) )
		else
			_filedir 'rpm'
		fi
		;;
	-@(e|-erase))
		if [[ "$cur" == -* ]]; then
			COMPREPLY=( $( compgen -W '--allmatches --noscripts \
			--notriggers --nodeps --test --repackage' -- $cur ) )
		else
			_rpm_installed_packages "$nodig" "$nosig"
		fi
		;;
	-@(q*|-query))
		# check whether we're doing file completion
		if [ "${COMP_LINE#* -*([^ -])f}" != "$COMP_LINE" ]; then
		    if [[ "$cur" == -* ]]; then
			COMPREPLY=( $( compgen -W '--scripts --root \
				--rcfile --requires --ftpport --ftpproxy \
				--httpproxy --httpport --provides --triggers \
				--dump --changelog --dbpath \
				--last --filesbypkg \
				--info --list --state \
				--docfiles --configfiles --queryformat \
				--conflicts --obsoletes \
				--nodigest --nosignature \
				--suggests --enhances \
				--triggerscripts' -- $cur ) )
		    else
			_filedir
		    fi
		elif [ "${COMP_LINE#* -*([^ -])g}" != "$COMP_LINE" ]; then
			_rpm_groups
		elif [ "${COMP_LINE#* -*([^ -])p}" != "$COMP_LINE" ]; then
			# uninstalled package completion
			if [[ "$cur" == -* ]]; then
				COMPREPLY=( $( compgen -W '--scripts --root \
				--rcfile --whatprovides --whatrequires \
				--requires --triggeredby --ftpport --ftpproxy \
				--httpproxy --httpport --provides --triggers \
				--dump --changelog --dbpath --filesbypkg \
				--define --eval --pipe --showrc --info --list \
				--state --docfiles --configfiles --queryformat\
				--conflicts --obsoletes --nodigest \
				--nosignature' -- $cur ) )
			else
				_filedir 'rpm'
			fi
		else
			# installed package completion
			if [[ "$cur" == -* ]]; then
				COMPREPLY=( $( compgen -W '--scripts --root \
				--rcfile --whatprovides --whatrequires \
				--requires --triggeredby --ftpport --ftpproxy \
				--httpproxy --httpport --provides --triggers \
				--dump --changelog --dbpath --specfile \
				--querybynumber --last --filesbypkg --define \
				--eval --pipe --showrc --info --list --state \
				--docfiles --configfiles --queryformat \
				--conflicts --obsoletes --pkgid --hdrid \
				--fileid --tid --nodigest --nosignature \
				--triggerscripts' -- $cur ) )
			elif [ "${COMP_LINE#* -*([^ -])a}" == "$COMP_LINE" ]; then
				_rpm_installed_packages "$nodig" "$nosig"
			fi
		fi
		;;
	-@(K*|-checksig))
		if [[ "$cur" == -* ]]; then
			COMPREPLY=( $( compgen -W '--nopgp --nogpg --nomd5 \
					--nodigest --nosignature' -- $cur ) )
		else
			_filedir 'rpm'
		fi
		;;
	-@([Vy]*|-verify))
		if [[ "$cur" == -* ]]; then
			COMPREPLY=( $( compgen -W '--root --rcfile --dbpath \
			--nodeps --nogroup --nolinkto --nomode --nomtime \
			--nordev --nouser --nofiles --noscripts --nomd5 \
			--querytags --specfile --whatrequires --whatprovides \
			--nodigest --nosignature' -- $cur ) )
		# check whether we're doing file completion
		elif [ "${COMP_LINE#* -*([^ -])f}" != "$COMP_LINE" ]; then
			_filedir
		elif [ "${COMP_LINE#* -*([^ -])g}" != "$COMP_LINE" ]; then
			_rpm_groups
		elif [ "${COMP_LINE#* -*([^ -])p}" != "$COMP_LINE" ]; then
			_filedir 'rpm'
		else
			_rpm_installed_packages "$nodig" "$nosig"
		fi
		;;
	-[bt]*)
		if [[ "$cur" == -* ]]; then
			COMPREPLY=( $( compgen -W '--short-circuit --timecheck \
			--clean --rmsource --rmspec --test --sign --buildroot \
			--target --nobuild --nodeps --nodirtokens' -- $cur ) )
		elif [[ ${COMP_WORDS[1]} == -b* ]]; then
			_filedir 'spec'
		else
			_filedir '@(tgz|tar.@(gz|bz2|lzma))'
		fi
		;;
	--re@(build|compile))
		if [[ "$cur" == -* ]]; then
			COMPREPLY=( $( compgen -W '--nodeps --rmsource \
			  --rmspec --sign --nodirtokens --target' -- $cur ) )
		else
			_filedir '?(no)src.rpm'
		fi
		;;
	--tarbuild)
		_filedir '@(tgz|tar.@(gz|bz2|lzma))'
		;;
	--@(re|add)sign)
		_filedir 'rpm'
		;;
	--set@(perms|gids))
		_rpm_installed_packages "$nodig" "$nosig"
		;;
	--@(clean|rms@(ource|pec)))
		if [[ "$cur" == -* ]]; then
			COMPREPLY=( $( compgen -W '--clean --rmsource \
					--rmspec' -- $cur ) )
		else
			_filedir 'spec'
		fi
		;;
	--@(import|dbpath|root))
		if [[ "$cur" == -* ]]; then
			COMPREPLY=( $( compgen -W '--import --dbpath --root' \
					-- $cur ) )
		else
			_filedir
		fi
		;;
	esac

	return 0
}
complete -F _rpm $filenames rpm rpmbuild
}
