#!/usr/bin/env bash

# forked from spikegrobstein/fzf-menu.  MIT license applies.
set -o errexit -o nounset -o pipefail

GREEN_START='\033[01;32m'
COLOR_RESET='\033[0m'
get_selection() {
	{ get_applications; get_programs_in_path; } \
		| fzf \
		--ansi \
		--preview="[[ {} == *'.desktop' ]] && cat \$(echo {} | awk '{print \$NF}') || echo \$(PAGER=cat whatis {})" \
		--preview-window=right:60%:wrap \
		--bind=ctrl-space:toggle-preview \
		--header="Select a program to launch"
}

get_programs_in_path() {
	local find_prog
	local find_args
	# my benchmarks show that GNU find > fd > BSD find
	if [[ -n "${FIND_PROG:-}" ]]; then
		find_prog=$FIND_PROG
		find_args=${FIND_ARGS:-}
	elif find / -maxdepth 0 -executable &>/dev/null || command -v gfind &>/dev/null; then
		# GNU find
		find_prog="$(command -v gfind || echo find) -L"
		find_args="-maxdepth 1 -executable -type f,l -printf %f\n"
	elif command -v fd > /dev/null; then
		find_prog="fd ."
		find_args="--hidden --max-depth=1 --type=executable --follow --format {/}"
	else
		# BSD find
		find_prog="find"
		find_args="-maxdepth 1 -perm +111 -type f,l -exec basename {} ;"
	fi

	local pathDeduped=$(printf '%s\n' $PATH | tr ':' '\n' | uniq )
	for p in $pathDeduped; do
		$find_prog $p $find_args 2>/dev/null || true
	done \
		| awk '!x[$0]++'
		# awk removes duplicates without sorting.  Thanks https://stackoverflow.com/a/11532197/6100005 \
}

get_applications() {
	local applicationPathsDeduped=$(printf '%s\n' ${XDG_DATA_DIRS:-/usr/share} | tr ':' '\n' | uniq )
	for p in $applicationPathsDeduped; do
		# TODO: support fd
		for app in $(find "$p"/applications -maxdepth 1 -type f,l -name '*.desktop' 2>/dev/null); do
			local appname=$(sed -n '0,/^Name=/{s/^Name=//p}' $app)
			printf "${GREEN_START}$appname${COLOR_RESET} : $app\n"
		done
	done
}

launch() {
	if [[ $1 == *'.desktop' ]]; then
		#exec nohup zsh -c "(gio launch $1) & disown ; sleep 3"
		exec nohup zsh -c "(setsid -f gio launch $1) & disown ; sleep 0.5"
	else
		if command -v setsid > /dev/null; then
			exec setsid -f $1 > /dev/null 2>&1
		fi
		exec $1
	fi
}

if [[ ${1:-} == "--list-programs" ]]; then
	get_programs_in_path
	exit 0
fi

if selection=$( get_selection ); then
	launch "$(echo $selection | awk '{print $NF}')"
fi

