# perf bash and zsh completion
# SPDX-License-Identifier: GPL-2.0

# Taken from git.git's completion script.
__my_reassemble_comp_words_by_ref()
{
	local exclude i j first
	# Which word separators to exclude?
	exclude="${1//[^$COMP_WORDBREAKS]}"
	cword_=$COMP_CWORD
	if [ -z "$exclude" ]; then
		words_=("${COMP_WORDS[@]}")
		return
	fi
	# List of word completion separators has shrunk;
	# re-assemble words to complete.
	for ((i=0, j=0; i < ${#COMP_WORDS[@]}; i++, j++)); do
		# Append each nonempty word consisting of just
		# word separator characters to the current word.
		first=t
		while
			[ $i -gt 0 ] &&
			[ -n "${COMP_WORDS[$i]}" ] &&
			# word consists of excluded word separators
			[ "${COMP_WORDS[$i]//[^$exclude]}" = "${COMP_WORDS[$i]}" ]
		do
			# Attach to the previous token,
			# unless the previous token is the command name.
			if [ $j -ge 2 ] && [ -n "$first" ]; then
				((j--))
			fi
			first=
			words_[$j]=${words_[j]}${COMP_WORDS[i]}
			if [ $i = $COMP_CWORD ]; then
				cword_=$j
			fi
			if (($i < ${#COMP_WORDS[@]} - 1)); then
				((i++))
			else
				# Done.
				return
			fi
		done
		words_[$j]=${words_[j]}${COMP_WORDS[i]}
		if [ $i = $COMP_CWORD ]; then
			cword_=$j
		fi
	done
}

# Define preload_get_comp_words_by_ref="false", if the function
# __perf_get_comp_words_by_ref() is required instead.
preload_get_comp_words_by_ref="true"

if [ $preload_get_comp_words_by_ref = "true" ]; then
	type _get_comp_words_by_ref &>/dev/null ||
	preload_get_comp_words_by_ref="false"
fi
[ $preload_get_comp_words_by_ref = "true" ] ||
__perf_get_comp_words_by_ref()
{
	local exclude cur_ words_ cword_
	if [ "$1" = "-n" ]; then
		exclude=$2
		shift 2
	fi
	__my_reassemble_comp_words_by_ref "$exclude"
	cur_=${words_[cword_]}
	while [ $# -gt 0 ]; do
		case "$1" in
		cur)
			cur=$cur_
			;;
		prev)
			prev=${words_[$cword_-1]}
			;;
		words)
			words=("${words_[@]}")
			;;
		cword)
			cword=$cword_
			;;
		esac
		shift
	done
}

# Define preload__ltrim_colon_completions="false", if the function
# __perf__ltrim_colon_completions() is required instead.
preload__ltrim_colon_completions="true"

if [ $preload__ltrim_colon_completions = "true" ]; then
	type __ltrim_colon_completions &>/dev/null ||
	preload__ltrim_colon_completions="false"
fi
[ $preload__ltrim_colon_completions = "true" ] ||
__perf__ltrim_colon_completions()
{
	if [[ "$1" == *:* && "$COMP_WORDBREAKS" == *:* ]]; then
		# Remove colon-word prefix from COMPREPLY items
		local colon_word=${1%"${1##*:}"}
		local i=${#COMPREPLY[*]}
		while [[ $((--i)) -ge 0 ]]; do
			COMPREPLY[$i]=${COMPREPLY[$i]#"$colon_word"}
		done
	fi
}

__perfcomp ()
{
	COMPREPLY=( $( compgen -W "$1" -- "$2" ) )
}

__perfcomp_colon ()
{
	__perfcomp "$1" "$2"
	if [ $preload__ltrim_colon_completions = "true" ]; then
		__ltrim_colon_completions $cur
	else
		__perf__ltrim_colon_completions $cur
	fi
}

__perf_prev_skip_opts ()
{
	local i cmd_ cmds_

	let i=cword-1
	cmds_=$($cmd $1 --list-cmds)
	prev_skip_opts=()
	while [ $i -ge 0 ]; do
		if [[ ${words[i]} == $1 ]]; then
			return
		fi
		for cmd_ in $cmds_; do
			if [[ ${words[i]} == $cmd_ ]]; then
				prev_skip_opts=${words[i]}
				return
			fi
		done
		((i--))
	done
}

__perf_main ()
{
	local cmd

	cmd=${words[0]}
	COMPREPLY=()

	# Skip options backward and find the last perf command
	__perf_prev_skip_opts
	# List perf subcommands or long options
	if [ -z $prev_skip_opts ]; then
		if [[ $cur == --* ]]; then
			cmds=$($cmd --list-opts)
		else
			cmds=$($cmd --list-cmds)
		fi
		__perfcomp "$cmds" "$cur"
	# List possible events for -e option
	elif [[ $prev == @("-e"|"--event") &&
		$prev_skip_opts == @(record|stat|top) ]]; then

		local cur1=${COMP_WORDS[COMP_CWORD]}
		local raw_evts=$($cmd list --raw-dump)
		local arr s tmp result cpu_evts

		# aarch64 doesn't have /sys/bus/event_source/devices/cpu/events
		if [[ `uname -m` != aarch64 ]]; then
			cpu_evts=$(ls /sys/bus/event_source/devices/cpu/events)
		fi

		if [[ "$cur1" == */* && ${cur1#*/} =~ ^[A-Z] ]]; then
			OLD_IFS="$IFS"
			IFS=" "
			arr=($raw_evts)
			IFS="$OLD_IFS"

			for s in ${arr[@]}
			do
				if [[ "$s" == *cpu/* ]]; then
					tmp=${s#*cpu/}
					result=$result" ""cpu/"${tmp^^}
				else
					result=$result" "$s
				fi
			done

			evts=${result}" "${cpu_evts}
		else
			evts=${raw_evts}" "${cpu_evts}
		fi

		if [[ "$cur1" == , ]]; then
			__perfcomp_colon "$evts" ""
		else
			__perfcomp_colon "$evts" "$cur1"
		fi
	else
		# List subcommands for perf commands
		if [[ $prev_skip_opts == @(kvm|kmem|mem|lock|sched|
			|data|help|script|test|timechart|trace) ]]; then
			subcmds=$($cmd $prev_skip_opts --list-cmds)
			__perfcomp_colon "$subcmds" "$cur"
		fi
		# List long option names
		if [[ $cur == --* ]];  then
			subcmd=$prev_skip_opts
			__perf_prev_skip_opts $subcmd
			subcmd=$subcmd" "$prev_skip_opts
			opts=$($cmd $subcmd --list-opts)
			__perfcomp "$opts" "$cur"
		fi
	fi
}

if [[ -n ${ZSH_VERSION-} ]]; then
	autoload -U +X compinit && compinit

	__perfcomp ()
	{
		emulate -L zsh

		local c IFS=$' \t\n'
		local -a array

		for c in ${=1}; do
			case $c in
			--*=*|*.) ;;
			*) c="$c " ;;
			esac
			array[${#array[@]}+1]="$c"
		done

		compset -P '*[=:]'
		compadd -Q -S '' -a -- array && _ret=0
	}

	__perfcomp_colon ()
	{
		emulate -L zsh

		local cur_="${2-$cur}"
		local c IFS=$' \t\n'
		local -a array

		if [[ "$cur_" == *:* ]]; then
			local colon_word=${cur_%"${cur_##*:}"}
		fi

		for c in ${=1}; do
			case $c in
			--*=*|*.) ;;
			*) c="$c " ;;
			esac
			array[$#array+1]=${c#"$colon_word"}
		done

		compset -P '*[=:]'
		compadd -Q -S '' -a -- array && _ret=0
	}

	_perf ()
	{
		local _ret=1 cur cword prev
		cur=${words[CURRENT]}
		prev=${words[CURRENT-1]}
		let cword=CURRENT-1
		emulate ksh -c __perf_main
		let _ret && _default && _ret=0
		return _ret
	}

	compdef _perf perf
	return
fi

type perf &>/dev/null &&
_perf()
{
	if [[ "$COMP_WORDBREAKS" != *,* ]]; then
		COMP_WORDBREAKS="${COMP_WORDBREAKS},"
		export COMP_WORDBREAKS
	fi

	if [[ "$COMP_WORDBREAKS" == *:* ]]; then
		COMP_WORDBREAKS="${COMP_WORDBREAKS/:/}"
		export COMP_WORDBREAKS
	fi

	local cur words cword prev
	if [ $preload_get_comp_words_by_ref = "true" ]; then
		_get_comp_words_by_ref -n =:, cur words cword prev
	else
		__perf_get_comp_words_by_ref -n =:, cur words cword prev
	fi
	__perf_main
} &&

complete -o bashdefault -o default -o nospace -F _perf perf 2>/dev/null \
	|| complete -o default -o nospace -F _perf perf
