#!/bin/sh

# Copyright (C) 2025-2026 Daniel Baumann <daniel@debian.org>
#
# SPDX-License-Identifier: GPL-3.0+
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <https://www.gnu.org/licenses/>.

set -e

PROJECT="bfh"
SOFTWARE="bfh-tools"
PROGRAM="bfh"
COMMAND="$(basename ${0})"

HOOKS="/etc/${PROJECT}/${PROJECT}.hooks"

Parameters ()
{
	GETOPT_LONGOPTIONS="directory:,simulate,dry-run,quiet,help,"
	GETOPT_OPTIONS="d:,v,q,h,"

	PARAMETERS="$(getopt --longoptions ${GETOPT_LONGOPTIONS} --name=${COMMAND} --options ${GETOPT_OPTIONS} --shell sh -- "${@}")"

	if [ "${?}" != "0" ]
	then
		echo "'${COMMAND}': getopt exit" >&2
		exit 1
	fi

	eval set -- "${PARAMETERS}"

	while true
	do
		case "${1}" in
			-d|--directory)
				DIRECTORY="${2}"
				shift 2
				;;

			--simulate|--dry-run)
				SIMULATE="true"
				shift 1
				;;

			-q|--quiet)
				QUIET="true"
				shift 1
				;;

			-h|--help)
				Usage
				exit 0
				;;

			--)
				shift 1
				break
				;;

			*)
				echo "'${COMMAND}': getopt error" >&2
				exit 1
				;;
		esac
	done
}

Usage ()
{
	echo "Usage: ${COMMAND} -d|--directory DIRECTORY [--simulate|--dry-run] [-q|--quiet]" >&2
	echo "Usage: ${COMMAND} -h|--help" >&2
	echo
	echo "See ${PROGRAM}_${COMMAND}(1), ${PROGRAM}(1) and ${SOFTWARE}(7) for more information."

	exit 1
}

Parameters "${@}"

if [ -z "${DIRECTORY}" ]
then
	Usage
fi

Run ()
{
	COMMANDS="${@}"

	case "${SIMULATE}" in
		true)
			echo ${COMMANDS}
			;;

		*)
			case "${QUIET}" in
				true)
					${COMMANDS} > /dev/null 2>&1
					;;

				*)
					echo ${COMMANDS}
					${COMMANDS}
					;;
			esac
			;;
	esac
}

Chown ()
{
	DIRECTORY="${1}"

	SHARE="$(basename ${DIRECTORY})"
	DEPARTMENT="$(basename $(dirname ${DIRECTORY}))"

	case "${DEPARTMENT}" in
		Users|nextcloud-data|home)
			ID="$(id ${SHARE} | awk '{ print $1 }' | sed -e 's|.*=||' -e 's|(.*||')"
			GID="$(id ${SHARE} | awk '{ print $2 }' | sed -e 's|.*=||' -e 's|(.*||')"

			Run chown ${ID}:${GID} ${SHARE} -R
			Run chown ${ID}:root ${SHARE}
			;;

		*)
			GROUP_READ="IDM.perm.storage.$(echo ${DEPARTMENT} | tr [A-Z] [a-z])_$(basename ${SHARE} .bfh.science | tr [A-Z] [a-z]).read"
			GROUP_WRITE="IDM.perm.storage.$(echo ${DEPARTMENT} | tr [A-Z] [a-z])_$(basename ${SHARE} .bfh.science | tr [A-Z] [a-z]).write"

			if [ -n "${GROUP_WRITE}" ]
			then
				Run chown root:${GROUP_WRITE} "${SHARE}"
				Run chgrp -R ${GROUP_WRITE} "${SHARE}"
			else
				if [ -n "${GROUP_READ}" ]
				then
					Run chown root:${GROUP_READ} "${SHARE}"
					Run chgrp -R ${GROUP_READ} "${SHARE}"
				else
					Run chown root:root "${SHARE}"
					Run chgrp -R root "${SHARE}"
				fi
			fi
			;;
	esac
}

Chmod ()
{
	DIRECTORY="${1}"

	SHARE="$(basename ${DIRECTORY})"
	DEPARTMENT="$(basename $(dirname ${DIRECTORY}))"

	case "${DEPARTMENT}" in
		Users|nextcloud-data|home)
			MODE="user"
			;;

		*)
			MODE="group"
			;;
	esac

	case "FIXME" in
		BFH)
			case "${SHARE}" in
				Geodata|UAVimages)
					MODE="other"
					;;

				*)
					MODE="group"
					;;
			esac
			;;

		HAFL)
			case "${SHARE}" in
				WWI-Geodata)
					MODE="other"
					;;

				*)
					MODE="group"
					;;
			esac
			;;
	esac

	case "${MODE}" in
		user)
			Run chmod 0706 ${SHARE}
			;;

		group)
			Run chmod g+s "${SHARE}"
			Run chmod 0770 "${SHARE}"

			Run find "${SHARE}" -type d -exec chmod 0770 {} +
			Run find "${SHARE}" -type f -exec chmod 0660 {} +
			;;

		other)
			Run chmod g+s "${SHARE}"

			# public data
			Run chmod 0775 "${SHARE}"

			# world-readable
			Run find "${SHARE}" -type d -exec chmod 0775 {} +

			# world-readable
			Run find "${SHARE}" -type f -exec chmod 0664 {} +
			;;
	esac
}

ACL ()
{
	DIRECTORY="${1}"

	SHARE="$(basename ${DIRECTORY})"
	DEPARTMENT="$(basename $(dirname ${DIRECTORY}))"

	GROUPS_READ="IDM.perm.storage.$(echo ${DEPARTMENT} | tr [A-Z] [a-z])_$(basename ${SHARE} .bfh.science | tr [A-Z] [a-z]).read"
	GROUPS_WRITE="IDM.perm.storage.$(echo ${DEPARTMENT} | tr [A-Z] [a-z])_$(basename ${SHARE} .bfh.science | tr [A-Z] [a-z]).write"

	# remove all ACLs
	Run setfacl -b -k -P -R "${SHARE}"

	case "${SHARE}" in
		FIXME)
			OTHER_READ=",o::rx"
			;;

		WWI-SNSF-Togo|MUS-Ehrenreich|prototypes-hkb.bfh.science|projects-hkb.bfh.science|dataviz.bfh.science|IS-A-Help|IDS-img)
			GROUPS_READ="${GROUPS_READ} www-data"
			;;

		LNI-team)
			;;

		LNI-*)
			GROUPS_READ="${GROUPS_READ} IDM.ser-its.pers-vma"
			;;

		*)
			OTHER_READ=""
			;;
	esac

	case "${DEPARTMENT}" in
		Users|nextcloud-data|home)
			;;

		*)
			if [ -n "${GROUPS_READ}" ]
			then
				for GROUP_READ in ${GROUPS_READ}
				do
					Run setfacl -P -R -m g:${GROUP_READ}:rx${OTHER_READ} "${SHARE}"
					Run setfacl -P -R -d -m g:${GROUP_READ}:rx${OTHER_READ} "${SHARE}"
				done
			fi

			if [ -n "${GROUPS_WRITE}" ]
			then
				for GROUP_WRITE in ${GROUPS_WRITE}
				do
					Run setfacl -P -R -m g:${GROUP_WRITE}:rwx${OTHER_READ} "${SHARE}"
					Run setfacl -P -R -d -m g:${GROUP_WRITE}:rwx${OTHER_READ} "${SHARE}"
				done
			fi
			;;
	esac
}

# Pre hooks
for FILE in "${HOOKS}/${COMMAND}.pre"* "${HOOKS}/pre.${COMMAND}".* "${HOOKS}/all.pre"* "${HOOKS}/pre.all".*
do
	if [ -x "${FILE}" ]
	then
		"${FILE}"
	fi
done

################################################################################
# Run command
################################################################################

# Dropping sssd cache
if [ -e /usr/sbin/sss_cache ]
then
	sss_cache -E
fi

DIRECTORY="$(readlink -f ${DIRECTORY})"

case "${QUIET}" in
	true)
		;;

	*)
		echo "Begin ${DIRECTORY}:"
		;;
esac

cd "$(dirname ${DIRECTORY})"
mkdir -p "${DIRECTORY}"

Chown "${DIRECTORY}"
Chmod "${DIRECTORY}"
ACL "${DIRECTORY}"

case "${QUIET}" in
	true)
		;;

	*)
		echo "End ${DIRECTORY}:"
		;;
esac

################################################################################

# Post hooks
for FILE in "${HOOKS}/${COMMAND}.post"* "${HOOKS}/post.${COMMAND}".* "${HOOKS}/all.post"* "${HOOKS}/post.all".*
do
	if [ -x "${FILE}" ]
	then
		"${FILE}"
	fi
done
