#!/usr/bin/env bash
# rlisthosts -- helper for rdo/rup to discover hosts
#
# Might use LDAP one day, but for now it's just a static list (instead of
# having that list hardcoded in rup, then copied to other tools).

. lib.bash || exit

usage() {
	echo "Usage: ${0##*/} [+]<host|@group>..."
	echo
	echo "Produce a list of hostnames, expanding '@group' specifications."
	echo "Comma-separated items are accepted and expanded to space-separated."
	echo
	echo_opt "host, @grp"	"add single host or the specified group"
	echo_opt "+host, +@grp"	"append to default list, instead of replacing"
	echo_opt "-a"		"add all hosts from all groups"
	echo_opt "-l"		"list known groups and exit"
}

# Predefine default groups
declare -A groups
groups[default]="wolke sky star ember wind dust"
groups[all]="@default myth"

if [[ -e ~/.config/rlisthosts ]]; then
	while read -r alias rest; do
		if [[ $alias == [!#]* ]]; then
			groups[$alias]=$rest
		fi
	done < ~/.config/rlisthosts
fi

# Infinite recursion check
if (( ++RLISTHOSTS_DEPTH > 10 )); then
	vdie "recursion depth exceeded"
fi
export RLISTHOSTS_DEPTH

# Accept comma-separated args (e.g. from 'rdo -H a,b,c') as well as separate
set -f
set -- ${*//,/ }
set +f

(( $# )) || set -- @default

hosts=
for arg; do
	if [[ $arg == +* ]]; then
		arg=${arg#+}
		hosts=${groups[default]}
	fi
	case $arg in
		--help)
			usage; exit 0;;
		-a)
			set -f
			next=(${groups[*]})
			set +f
			for host in "${next[@]}"; do
				case $host in
				@*)	;;
				*)	hosts+=" $host";;
				esac
			done;;
		-l)
			for group in "${!groups[@]}"; do
				echo "$group = ${groups[$group]}"
			done; exit 0;;
		-*)
			vdie "unknown option '$arg'";;
		@*)
			if [[ ! ${groups[${arg#@}]} ]]; then
				vdie "unknown group '$arg'"
			fi
			set -f
			next=(${groups[${arg#@}]})
			set +f
			for host in "${next[@]}"; do
				case $host in
				@*)	hosts+=" $(rlisthosts "$host")";;
				*)	hosts+=" $host";;
				esac
			done;;
		*)
			hosts+=" $arg";;
	esac
done

set -f
hosts=${hosts//,/ }

declare -A seen=()
for host in $hosts; do
	if [[ ! ${seen[$host]} ]]; then
		seen[$host]=1
		echo -n "$host "
	fi
done
echo ""

set +f
