#! /bin/bash
set -e

[ "${TWIKI_ADMIN_DEBUG}" ] || TWIKI_ADMIN_DEBUG=0
declare -r TWIKI_ADMIN_DEBUG

if [[ ${TWIKI_ADMIN_DEBUG} -gt 2 ]] ; then
	set -x
fi

__twa_bindir=$(dirname "$0")

# Obtain full paths with a dirty trick :)
#
__twa_full_path ()
{
	local base='' path=$1

	if [[ ! -d $1 ]] ; then
		base="/${1##*/}"
		path=${1%/*}
	fi

	pushd "${path}" > /dev/null
	path=$(pwd)
	popd > /dev/null

	echo "${path}${base}"
}


# Get full bindir
#
__twa_bindir=$(__twa_full_path "${__twa_bindir}")

# Configuration file
#
__twa_config_file=${TWIKI_ADMIN_CONF:-/etc/admintools/twiki-admin.conf}

# Mark some variables as read-only
declare -r __twa_bindir __twa_config


# Utility functions which actions can use
#
__twa_usage_and_exit ()
{
	local usage line impl desc

	impl="${__twa_bindir}/twiki-admin-${__twa_action}"
	usage=$(sed -e '/^##:/p' -e d "${impl}")
	desc=$(sed -e '/^##-/p' -e d "${impl}")

	echo "Usage: twiki-admin ${__twa_action}${usage#\#\#:}"
	echo "  ${desc#\#\#-}"
	echo
	echo "Arguments:"
	while read -r line ; do
		echo "  ${line#\#\#+}"
	done < <( sed -e '/^##+/p' -e d "${impl}" )
	echo
	exit 1
}


# Usage: __twa_backup_file filepath [backupsuffix]
#
__twa_backup_file ()
{
	if [[ -r $1 ]] ; then
		cp "${1}" "${1}.${2:-old}"
	fi
}


# Prints a message and exits with an error
#
__twa_die ()
{
	[ "$*" ] && echo "twiki-admin-${__twa_action}: $*" >&2
	exit 2
}


# Runs a command, if TWIKI_ADMIN_DEBUG is set to a non-empty value, then
# commands are printed out before executing them. Otherwise, standard output
# of commands is silently sent to /dev/null.
#
__twa_do ()
{
	if [[ ${TWIKI_ADMIN_DEBUG} -gt 0 ]] ; then
		echo "*** $*"
		if [[ ${TWIKI_ADMIN_DEBUG} -lt 2 ]] ; then
			"$@"
		fi
	else
		"$@" > /dev/null
	fi
}


__twa_info ()
{
	if [[ ${TWIKI_ADMIN_DEBUG} -gt 0 ]] ; then
		echo "=== $*"
	fi
}


# Obtain lock
#
__twa_run_locked ()
{
	local name="/var/lock/twiki-admin.lock"
	local link="${name}.held"

	touch "${name}"
	if ! ln "${name}" "${link}" &> /dev/null ; then
		__vsa_die "Coult not acquire lock '${link}'"
	fi
	trap "rm -f '${link}'" EXIT
}

__twa_unlock ()
{
	rm -f /var/lock/twiki-admin.lock.held
}


# Monstruous sed command chain used by the configuration file loader...
#
__twa_config_sed='
/^_=/d
/^PWD=/d
/^IFS=/d
/^PS.=/d
/^BASH/d
/^TERM=/d
/^PATH=/d
/^SHELL/d
/^SHLVL=/d
/^GROUPS=/d
/^E\\?UID=/d
/^P\\?PID=/d
/^DIRSTACK=/d
/^PIPESTATUS=/d
/^OPT\(ERR\|IND\)=/d
/^\(OS\|MACH\)TYPE=/d
/^HOST\(NAME\|TYPE\)=/d
s/^/%s_/
'


# Loads the configuration file
#
# XXX Be careful when trying to understand this, heavy shell-fu follows
#     for cleaning up the environment thus the config file is sourced in
#     a sandboxed way.
#

__twa_config ()
{
	[[ -r ${__twa_config_file} ]] \
		|| __twa_die "Configuration file '${__twa_config_file}' not readable"

	# Modify the sed script above to include the user-defined prefix
	#
	local cfg_sed=$(printf "${__twa_config_sed}" "${2:-cfg}")

	# Pick the input into a variable, plus add a "declare" statement at the
	# end so variables will be dumped after all defines have been done.
	#
	local cfg_input="$(< "${__twa_config_file}") ; declare"

	# Loading the configuration file works this way:
	#
	#  1. "env -" clears the environment
	#  2. We define the variables for which substitutes are allowed in config
	#  3. We run the above input in a subshell launched from "env"
	#  4. Then "sed" uses the above script to filter out things we do not want
	#  5. The resulting script is eval'd -- but we save it first to a variable
	#     so we can print it when debugging is requested.
	#
	local cfg_script="$(env - \
		wiki=$1 \
	    "${SHELL}" <<< "${cfg_input}" | sed "${cfg_sed}")"

	if [[ ${TWIKI_ADMIN_DEBUG} -gt 0 ]] ; then
		echo ">>> __twa_config $*"
		echo "${cfg_script}"
		echo "<<< __twa_config $*"
	fi >&2

	eval "${cfg_script}"
}


# Gets a list of user names in an Apache password file
#
# Usage: __twa_htpasswd_users passwdfile
#
__twa_htpasswd_users ()
{
	sed -e '/^[^:]\+:/s/:.*$//p' -e d "$1"
}




if [[ $# -eq 0 ]] || ! [ -r "${__twa_bindir}/twiki-admin-$1" ]
then
	# No action give: print action list
	echo "Usage: twiki-admin action [action-arguments...]"
	echo
	echo "Available actions:"
	for action in "${__twa_bindir}"/twiki-admin-* ; do
		action=${action##*/}
		description=$(sed -e '/^##-/p' -e d "${__twa_bindir}/${action}")
		printf "   %-10s %s\n" "${action#twiki-admin-}" "${description##\#\#-}"
	done
	echo
	echo "Use 'twiki-admin help action' for more information on a specific command"
	exit 1
fi


# Get action, save it, and pop it from the command line argument list
__twa_action=$1
shift


# Let it go!, go!!, go!!!
source "${__twa_bindir}/twiki-admin-${__twa_action}"


