#!/bin/bash

# Copyright (C) 2019 Mike Gabriel <mike.gabriel@das-netzwerkteam.de>
#
# 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 2 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


# This scripts resets a user profile (the .dot files and .dot dirs
# in $HOME).
#
# Always test before really executing...
#
# Dry-Run: itzks-reset-userprofile <user>
# ... then read its output!!!
#
# Really-do: itzks-reset-userprofile <user> really-do
#

this_DATE="$(date +%Y%m%d)"

this_USER="${USER}"
if [ "x${this_USER}" = "xroot" ]; then

	if [ "x${1}" != "x" ]; then
		this_USER="${1}"
	else
		echo "ERROR: specify an existing user name for user profile reset"
		exit 1
	fi

else
	echo "ERROR: $(basename $0) must run with super-user privileges"
	exit 2
fi

if ! id "${this_USER}" 1>/dev/null 2>/dev/null; then
	echo "ERROR: no such user known on this site"
	exit 3
fi

this_GROUP="$(id -gn "$this_USER")"

this_HOME="$(getent passwd ${this_USER} | cut -d ":" -f6)"

# if we are root, we cannot work over a network filesystem
if ! echo "${this_HOME}" | grep -qE "/skole/$(hostname -s)/home.*"; then
	echo "home directory not on this machine"
	exit 4
fi

if [ -d "${this_HOME}/.profile-reset-${this_DATE}" ]; then
	echo "ERROR: user profile has been reset today already, cannot do this twice on one day"
	exit 5
fi

really_DO="${2}"

if [ "x$really_DO" != "xreally-do" ]; then
	fake_cmd="echo -e"
	echo
	echo "########################################################################"
	echo
fi

$fake_cmd cd ${this_HOME}
$fake_cmd mkdir .profile-reset-${this_DATE}/
$fake_cmd chown ${this_USER}:${this_GROUP} .profile-reset-${this_DATE}/

echo
echo "Backing up configuration directories to ${this_HOME}/.profile-reset-${this_DATE}"
find . -maxdepth 1 -type d | grep -E '\./\..*' | while read confdir; do

	# don't back up this or older profile reset backups
	if echo "${confdir}" | grep -q -E '.*/\.profile-reset-[0-9]{8}$'; then
		continue
	fi

	# keep SSH and GnuPG configuration
	if [ "x${confdir}" = "x./.ssh" ]; then
		continue
	fi
	if [ "x${confdir}" = "x./.gnupg" ]; then
		continue
	fi

	$fake_cmd mv -v $confdir ".profile-reset-${this_DATE}/"
done

echo
echo "Backing up configuration files to ${this_HOME}/.profile-reset-${this_DATE}"
find . -maxdepth 1 -type f | grep -E '\./\..*' | while read conffile; do
	$fake_cmd mv -v $conffile .profile-reset-${this_DATE}/
done

echo
echo "Backing up special application data folders to ${this_HOME}/.profile-reset-${this_DATE}"

# FIXME: this needs to be adapted to XDG desktop folder naming
[ -d "${this_HOME}/Desktop" ] && {
	$fake_cmd mkdir "${this_HOME}/.profile-reset-${this_DATE}/Desktop/"
	$fake_cmd mv -v "${this_HOME}/Desktop/*.desktop" "${this_HOME}/.profile-reset-${this_DATE}/Desktop/"
}
[ -d "${this_HOME}/Schreibtisch" ] && {
	$fake_cmd mkdir "${this_HOME}/.profile-reset-${this_DATE}/Schreibtisch/"
	$fake_cmd mv -v "${this_HOME}/Schreibtisch" "${this_HOME}/.profile-reset-${this_DATE}/Schreibtisch/"
}

# FIXME: this is ITZkS specific, it needs to be "out-sourced"
[ -d "${this_HOME}/Netzwerkordner" ]   && $fake_cmd mv -v "${this_HOME}/Netzwerkordner" "${this_HOME}/.profile-reset-${this_DATE}/"

# GrandOrgue directories
[ -d "${this_HOME}/GrandOrgue" ]       && $fake_cmd mv -v "${this_HOME}/GrandOrgue" "${this_HOME}/.profile-reset-${this_DATE}/"
[ -d "${this_HOME}/GrandOrgueCache" ]  && $fake_cmd mv -v "${this_HOME}/GrandOrgueCache" "${this_HOME}/.profile-reset-${this_DATE}/"
[ -d "${this_HOME}/GrandOrgueConfig" ] && $fake_cmd mv -v "${this_HOME}/GrandOrgueConfig" "${this_HOME}/.profile-reset-${this_DATE}/"
[ -d "${this_HOME}/GrandOrgueData" ]   && $fake_cmd mv -v "${this_HOME}/GrandOrgueData" "${this_HOME}/.profile-reset-${this_DATE}/"

# arduino sketch book
[ -d "${this_HOME}/sketchbook" ]       && $fake_cmd mv -v "${this_HOME}/sketchbook" "${this_HOME}/.profile-reset-${this_DATE}/"

echo
echo "Re-creating a fresh user profile"
$fake_cmd cp -avT "/etc/skel/" "${this_HOME}/"

echo
echo "Fixing ownership of re-created user profile"
$fake_cmd chown -Rf "${this_USER}:${this_GROUP}" "${this_HOME}/"

echo
echo "Setting 0750/0640 mask for permissions on user directory"
$fake_cmd chmod -Rf g-w,o-rwx  "${this_HOME}/"

[ -d "${this_HOME}/public_html" ] && {
	echo
	echo "Making '${this_HOME}/public_html' accessible to the webserver"
	$fake_cmd chmod o+x "${this_HOME}"
	$fake_cmd chmod o+rx "${this_HOME}/public_html/"
}

echo
echo "Done"
if [ "x$really_DO" != "xreally-do" ]; then

	$fake_cmd cd -

	echo
	echo "########################################################################"

	echo
	echo "NOTICE: Only showing what would happen, use"
	echo
	echo "            $(basename $0) <user> really-do"
	echo
	echo "        to really enforce a user profile reset."
	echo
else

	cd - 1>/dev/null

fi
