# (C) 2023 Victorien Elvinger

# Completion script for the "pass" command.

function completion/pass {
    OPTIONS=( #>#
	"c:: --clip::; copy the password to clipboard"
	"--help"
	"q:: --qrcode::; encode the password in a QR Code"
	"--version"
	) #<#
	command -f completion//parseoptions -n
	case $ARGOPT in
		(-)
			command -f completion//completeoptions
			;;
		('')
			if [ ${WORDS[#]} -eq 1 ]; then
				command -f completion/pass::completecmd
				command -f completion/pass::passwords
			else
				typeset passcmd="${WORDS[2]}"
				command -f completion//parseoptions
				command -f completion//getoperands
				if command -vf "completion/pass::$passcmd:arg" >/dev/null 2>&1; then
					command -f "completion/pass::$passcmd:arg"
				elif [ ${WORDS[#]} -eq 0 ]; then
						command -f completion/pass::passwords
				fi
			fi
            ;;
    esac
}

function completion/pass::completecmd { #>>#
    complete -P "$PREFIX" -D "copy a password" cp
    complete -P "$PREFIX" -D "edit a password" edit
    complete -P "$PREFIX" -D "list passwords matching a name" find
    complete -P "$PREFIX" -D "generate a password" generate
    complete -P "$PREFIX" -D "git commands inside the password store" git
    complete -P "$PREFIX" -D "grep inside passwords" grep
    complete -P "$PREFIX" -D "show help" help
    complete -P "$PREFIX" -D "initialize  new  password store" init
    complete -P "$PREFIX" -D "insert a new password" insert
    complete -P "$PREFIX" -D "list passwords" list ls
    complete -P "$PREFIX" -D "move a password" mv
    complete -P "$PREFIX" -D "remove a password" rm
    complete -P "$PREFIX" -D "show a password" show
    complete -P "$PREFIX" -D "show version" version
	#<<#
}

function completion/pass::cp:arg {
	OPTIONS=( #>#
	"f --force; don't prompt when overriding a password"
	) #<#

	command -f completion//parseoptions
	case $ARGOPT in
		(-)
			command -f completion//completeoptions
			;;
		('')
			command -f completion//getoperands
			if [ ${WORDS[#]} -lt 2 ]; then
				command -f completion/pass::passwords
				command -f completion/pass::subfolders
			fi
			;;
	esac
}

function completion/pass::edit:arg {
    if [ ${WORDS[#]} -eq 1 ]; then
        command -f completion/pass::passwords
    fi
}

function completion/pass::generate:arg {
	OPTIONS=( #>#
	"c --clip; copy the password to clipboard"
	"f --force; override if a password with the same name exists"
	"i --in-place; update the password keeping other lines unchanged"
	"n --no-symbols; don't use any non-alphanumeric characters"
	) #<#

	command -f completion//parseoptions
	case $ARGOPT in
		(-)
			command -f completion//completeoptions
			;;
		('')
			command -f completion//getoperands
			if [ ${WORDS[#]} -eq 0 ]; then
				command -f completion/pass::passwords
			fi
			;;
	esac
}

function completion/pass::git:arg {
	# delegate to git completion
    command -f completion//reexecute
}

function completion/pass::grep:arg {
	# delegate to grep completion
    command -f completion//reexecute
}

function completion/pass::init:arg {
    OPTIONS=( #>#
	"p: --path:; path of the password store"
	) #<#

	command -f completion//parseoptions
	case $ARGOPT in
		(-)
			command -f completion//completeoptions
			;;
		('')
			command -f completion/pass::gpgids
			;;
	esac
}

function completion/pass::insert:arg {
	OPTIONS=( #>#
	"e --echo; don't print entered characters"
	"f --force; override if a password with the same name exists"
	"m --multiline; add several lines in the password file"
	) #<#

	command -f completion//parseoptions
	case $ARGOPT in
		(-)
			command -f completion//completeoptions
			;;
		('')
			command -f completion//getoperands
			if [ ${WORDS[#]} -eq 0 ]; then
				command -f completion/pass::passwords
			fi
			;;
	esac
}

function completion/pass::ls:arg {
    if [ ${WORDS[#]} -eq 1 ]; then
        command -f completion/pass::subfolders
    fi
}

function completion/pass::mv:arg {
	# same completion as `pass cp`
    command -f completion/pass::cp:arg
}

function completion/pass::show:arg {
	OPTIONS=( #>#
	"c:: --clip::; copy the password to clipboard"
	"q:: --qrcode::; encode the password in a QR Code"
	) #<#

	command -f completion//parseoptions
	case $ARGOPT in
		(-)
			command -f completion//completeoptions
			;;
		('')
			command -f completion//getoperands
			if [ ${WORDS[#]} -eq 0 ]; then
				command -f completion/pass::passwords
			fi
			;;
	esac
}

function completion/pass::rm:arg {
	OPTIONS=( #>#
	"f --force; don't prompt before removing"
	"r --recursive; remove passwords recursively if it is a directory"
	) #<#

	command -f completion//parseoptions
	case $ARGOPT in
		(-)
			command -f completion//completeoptions
			;;
		('')
			# find first non-option argument parse options that modify completion behavior
			typeset OPTIND=2 isrec=0
			while [ $OPTIND -le ${WORDS[#]} ]; do
				case ${WORDS[OPTIND]} in
					(-r|--recursive)
						isrec=1
						;;
					(-?*)
						;;
					(*)
						break
						;;
				esac
				OPTIND=$((OPTIND+1))
			done

			if [ $OPTIND -gt ${WORDS[#]} ]; then
				if [ $isrec -eq 1 ]; then
					command -f completion/pass::subfolders
				else
					command -f completion/pass::passwords
				fi
			fi
			;;
	esac
}

function completion/pass::passwords {
    typeset passdir="${PASSWORD_STORE_DIR:-"$HOME/.password-store"}"
	complete -P "$PREFIX" -- $(find -L "$passdir" -name '.git' -prune -o -name '*.gpg' -print 2>/dev/null | sed -e "s#${passdir}/\{0,1\}##" -e 's#\.gpg##' -e 's#\\#\\\\#g' -e 's#:#\\:#g')
}

function completion/pass::subfolders {
    typeset passdir="${PASSWORD_STORE_DIR:-"$HOME/.password-store"}"
	complete -P "$PREFIX" -- $(find -L "$passdir" -name '.git' -prune -o -type d -print | sed -e "s#${passdir}/\{0,1\}##" -e 's#\\#\\\\#g' -e 's#:#\\:#g')
}

function completion/pass::gpgids {
    # suggest emails and public key ids
	complete -P "$PREFIX" -- $(gpg2 --list-keys 2>/dev/null | grep '^uid.*>$' | sed -e 's/.*<\(.*\)>$/\1/') $(gpg2 --list-keys --with-colons 2> /dev/null | grep '^pub:' | cut -d: -f5)
}


# vim: set ft=sh ts=8 sts=8 sw=8 noet:
