#!/bin/bash -e
#
# Univention Directory Listener
#  resync modules
#
# Like what you see? Join us!
# https://www.univention.com/about-us/careers/vacancies/
#
# Copyright 2004-2024 Univention GmbH
#
# https://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <https://www.gnu.org/licenses/>.

STATE_DIR='/var/lib/univention-directory-listener/handlers'
MODULE_DIR='/usr/lib/univention-directory-listener/system'

main () {
	local cmd="${1:-}"
	shift || usage 1
	case "${cmd#--}" in
	resync) resync "$@" ;;
	status) state ;;
	modules) modules 0 ;;
	help|-h) usage 0 ;;
	*) usage 1 ;;
	esac
}

usage () {
	echo "$0: command [args]"
	echo "Commands:"
	echo "  resync module1...     Resyncronize module(s) DANGEROUS!"
	echo "  status                Show listener status"
	echo "  modules               Show modules and their status"
	exit "${1:-1}"
}

resync () {
	[ -n "${1:-}" ] || modules 2
	local i
	for i in "$@"
	do
		[ -f "$STATE_DIR/$i" ] || modules 2
	done

	systemctl stop univention-directory-listener
	echo "listener shutdown done"
	for i in "$@"
	do
		rm -f "$STATE_DIR/$i"
	done
	systemctl start univention-directory-listener
}

state () {
	local rv state master_id local_id last_trans rv module_name module_file module_state

	rv='' state=$(systemctl show univention-directory-listener.service --property SubState --value)
	systemctl is-active univention-directory-listener.service || rv="$FAIL"
	printf 'Listener status:\n %s%s%s\n\n' "${rv:-$OKAY}" "$state" "$RSET"

	rv='' master_id=$(/usr/share/univention-directory-listener/get_notifier_id.py) || rv="$FAIL"
	printf 'Current Notifier ID on "%s"\n %s%s%s\n\n' "$(ucr get ldap/master)" "${rv:-$OKAY}" "$master_id" "$RSET"

	rv='' local_id=$(cat /var/lib/univention-directory-listener/notifier_id) &&
		[ -n "$local_id" ] &&
		[ "$master_id" -eq "$local_id" ] ||
		rv="$FAIL"
	printf 'Last Notifier ID processed by local Listener:\n %s%s%s\n\n' "${rv:-$OKAY}" "$local_id" "$RSET"

	rv='' last_trans=$(tail -n1 /var/lib/univention-ldap/notify/transaction) &&
		[ -n "$last_trans" ] &&
		[ "${last_trans%% *}" -eq "$local_id" ] ||
		rv="$FAIL"
	printf 'Last transaction processed:\n %s%s%s\n\n' "${rv:-$OKAY}" "$last_trans" "$RSET"

	modules 0
}

modules () {
	echo "Modules:"
	for module_file in "$MODULE_DIR"/*.py
	do
		[ -f "$module_file" ] || continue
		rv=
		module_name=$(sed -rne "s/^name\s*=\s*['\"]([^'\"]+)['\"]\s*(#.*)?$/\1/p;T;q" "$module_file") || rv="$FAIL"
		[ -z "$module_name" ] && module_name=$(basename "$module_file" '.py')
		module_state=$(cat "$STATE_DIR/$module_name" 2>/dev/null) &&
			[ "$module_state" -eq 3 ] ||
			rv="$FAIL"
		printf '%d\t%s\t%s%s%s\n' "$module_state" "$module_name" "${rv:-$OKAY}" "$module_file" "$RSET"
	done
	exit "${1:-0}"
}

if [ -t 1 ] && [ -n "${TERM:-}" ] && [ "$TERM" != dumb ]
then
	RSET=$(tput op 2>/dev/null) FAIL=$(tput setaf 1 2>/dev/null) OKAY=$(tput setaf 2 2>/dev/null) || :
else
	RSET='' FAIL='' OKAY=''
fi

main "$@"
