#!/usr/bin/env -S bash -eu
#
#   Copyright 2022 -- Evilham <contact@evilham.com>
#
#   This file is part of DD
#
#   DD is free software: you can redistribute it and/or modify
#   it under the terms of the GNU Affero General Public License as published by
#   the Free Software Foundation, either version 3 of the License, or (at your
#   option) any later version.
#
#   DD 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 Affero General Public License for more
#   details.
#
#   You should have received a copy of the GNU Affero General Public License
#   along with DD. If not, see <https://www.gnu.org/licenses/>.
#
# SPDX-License-Identifier: AGPL-3.0-or-later

# General settings, dir, repo, branch. You usually do not want these changed.
DDSRC_DIR="${DDSRC_DIR:-/opt/src/DD}"
DDREPO_URL="${DDREPO_URL:-https://gitlab.com/DD-workspace/DD}"
DDBRANCH="${DDBRANCH:-main}"
DDLOG="${DDLOG:-dd-install.log}"

help() {
	cat <<EOF
Usage: $0 --install

Use the environment extensively to configure DD.
Any VARIABLE that is found in:
${DDREPO_URL:?}/-/raw/${DDBRANCH:?}/dd.conf.sample
Can be specified in this script's environment as DD_VARIABLE.
For example, use DD_DOMAIN to pre-configure the DOMAIN.

Furthermore, you can set DDIMG_LOGO_PNG and DDIMG_BACKGROUND_PNG to the path
of PNG files that will be used for the logo and background respectively.

This script will take care of installing all pre-requisites, pulling and
updating sources, applying workarounds for known bugs, etc.
EOF
}

case "${1:-}" in
	-h|--help)
		help
		exit
	;;
	""|--install)
	;;
	*)
		help
		exit 1
	;;
esac

check_config_interactive() {
	if [ -z "${DD_DOMAIN:-}" ]; then
		INTERACTIVE_INSTALL="YES"
		cat <<-EOF
		Interactive install detected!
		Please follow the instructions carefully:

		EOF
		read -rep "Under which DOMAIN will you install DD? " DD_DOMAIN
		export DD_DOMAIN

		cat <<-EOF


		You will need to setup DNS entries for:
		- [ ] moodle.${DD_DOMAIN}
		- [ ] nextcloud.${DD_DOMAIN}
		- [ ] wp.${DD_DOMAIN}
		- [ ] oof.${DD_DOMAIN}
		- [ ] sso.${DD_DOMAIN}
		- [ ] pad.${DD_DOMAIN}
		- [ ] admin.${DD_DOMAIN}
		- [ ] api.${DD_DOMAIN}


		EOF
	fi
	# TODO: perform some kind of DNS check to help with installation?
	if [ -z "${DD_TITLE_SHORT:-}" ]; then
		if [ -n "${INTERACTIVE_INSTALL:-}" ]; then
			read -rep "What is the short title of the DD instance? [DD] " DD_TITLE_SHORT
		fi
		if [ -z "${DD_TITLE_SHORT:-}" ]; then
			DD_TITLE_SHORT="DD"
		fi
		export DD_TITLE_SHORT
	fi
	if [ -z "${DD_TITLE:-}" ]; then
		if [ -n "${INTERACTIVE_INSTALL:-}" ]; then
			read -rep "What is the full title of the DD instance? [${DD_TITLE_SHORT}] " DD_TITLE
		fi
		if [ -z "${DD_TITLE:-}" ]; then
			DD_TITLE="${DD_TITLE_SHORT}"
		fi
		export DD_TITLE
	fi
	if [ -n "${INTERACTIVE_INSTALL:-}" ]; then
		read -rep "Do you want to use Let's Encrypt certificates? [Y/n] " USE_LETSENCRYPT
		case ${USE_LETSENCRYPT:-} in
			n*|N*)
				;;
			*)
				# Reuse user-provided info
				export DD_LETSENCRYPT_DNS="${DD_DOMAIN}"
				read -rep "Which email will you use for Let's Encrypt notifications? " \
					DD_LETSENCRYPT_EMAIL
				export DD_LETSENCRYPT_EMAIL
				read -rep "Generate a certificate for ${DD_DOMAIN}? (neds the DNS entry) [y/N] " \
					LE_ROOT_CERT
				case ${LE_ROOT_CERT:-} in
					y*|Y*)
						DD_LETSENCRYPT_DOMAIN_ROOT=true
						;;
					*)
						DD_LETSENCRYPT_DOMAIN_ROOT=false
						;;
				esac
				export DD_LETSENCRYPT_DOMAIN_ROOT
				;;
		esac

		read -rep "Path to the logo's PNG file (optional): " \
			DDIMG_LOGO_PNG
		read -rep "Path to the background's PNG file (optional): " \
			DDIMG_BACKGROUND_PNG

		cat <<-EOF
		About to install with following information:

		DOMAIN=${DD_DOMAIN}
		TITLE_SHORT=${DD_TITLE_SHORT}
		TITLE=${DD_TITLE}
		LETSENCRYPT_DNS=${DD_LETSENCRYPT_DNS}
		LETSENCRYPT_EMAIL=${DD_LETSENCRYPT_EMAIL:-}
		LETSENCRYPT_DOMAIN_ROOT=${DD_LETSENCRYPT_DOMAIN_ROOT:-}

		Custom logo in PNG (if requested): ${DDIMG_LOGO_PNG:-}
		Custom background in PNG (if requested): ${DDIMG_BACKGROUND_PNG:-}
		EOF
		read -rep "Is this correct? proceed with the install? [Y/n] " DO_INSTALL
		case ${DO_INSTALL:-} in
			n*|N*)
				exit
				;;
			*)
				;;
		esac
	fi
}

# Ensure we have all necessary info
check_config_interactive

# Read all environment variables (DD_ prefix removed)
DD_ENV="$(env | grep -E '^DD_' | cut -c 4-)"
DD_VARS="$(echo "${DD_ENV}" | cut -d = -f 1)"

# Ensure DDIMG_* paths are full
# TODO: ensure the images are .png files
if [ -n "${DDIMG_LOGO_PNG:-}" ]; then
	DDIMG_LOGO_PNG="$(realpath "${DDIMG_LOGO_PNG}")"
fi
if [ -n "${DDIMG_BACKGROUND_PNG:-}" ]; then
	DDIMG_BACKGROUND_PNG="$(realpath "${DDIMG_BACKGROUND_PNG}")"
fi

#
# START MANUAL INSTALL
#
# Ensure apt cache is up to date
apt-get update

# Ensure git is available
GIT="$(command -v git || true)"
if [ -z "${GIT:-}" ]; then
	apt-get install -y git
	GIT="$(command -v git)"
fi

# Create source dir and clone repo as necessary
if [ ! -d "${DDSRC_DIR:?}" ]; then
	mkdir -p "${DDSRC_DIR:?}"
	"${GIT:?}" clone "${DDREPO_URL:?}" "${DDSRC_DIR:?}"
	# Change to the requested branch
	"${GIT:?}" -C "${DDSRC_DIR:?}" checkout "${DDBRANCH:?}"
fi

# Change to the source dir
cd "${DDSRC_DIR:?}"

# Copy the custom directory
if [ ! -d "custom" ]; then
	cp -r custom.sample custom
fi

# Copy conf file
cp dd.conf.sample dd.conf

# Patch the configuration with the environment variables
# If installing manually, you'd edit `dd.conf` instead
for dd_var in ${DD_VARS:?}; do
	dd_val="$(echo "${DD_ENV}" | grep -E "^${dd_var:?}=" | cut -d = -f 2- | head -n 1)"
	./dd-ctl setconf "${dd_var:?}" "${dd_val:-}"
done

# Replace logos if requested
# If installing manually you'd replace:
# - custom/img/logo.png
# - custom/img/background.png
if [ -f "${DDIMG_LOGO_PNG:-}" ]; then
	cp "${DDIMG_LOGO_PNG:?}" "custom/img/logo.png"
fi
if [ -f "${DDIMG_BACKGROUND_PNG:-}" ]; then
	cp "${DDIMG_BACKGROUND_PNG:?}" "custom/img/background.png"
fi

# Update all repositories
./dd-ctl repo-update "${DDBRANCH:?}" 2>&1 | tee -a "${DDLOG}"
# Install all prerequisites
./dd-ctl prerequisites 2>&1 | tee -a "${DDLOG}"
# Fix insecure passwords
./dd-ctl securize 2>&1 | tee -a "${DDLOG}"
# Perform installation as per further instructions
./dd-ctl all 2>&1 | tee -a "${DDLOG}"

# Wait a tad to work around dd-sso issues
echo "Waiting a few seconds for things to settle..."
sleep 30
# Address timing dd-sso issue by restarting the containers
./dd-ctl down
./dd-ctl up

# Address Moodle custom settings, plugins and registration
NEXTCLOUD_ADMIN_USER="$(grep -E '^NEXTCLOUD_ADMIN_USER=' dd.conf | cut -d = -f 2-)"
NEXTCLOUD_ADMIN_PASSWORD="$(grep -E '^NEXTCLOUD_ADMIN_PASSWORD=' dd.conf | cut -d = -f 2-)"
docker exec -i -u nobody dd-apps-moodle sh -s <<EOF
php admin/cli/maintenance.php --enable
php admin/cli/upgrade.php --non-interactive
php theme/cbe/postinstall.php \
	--wwwroot="moodle.${DD_DOMAIN}" \
	--ncadmin="${NEXTCLOUD_ADMIN_USER}" \
	--ncpass="${NEXTCLOUD_ADMIN_PASSWORD}" \
	--sitename="${DD_TITLE}" \
	--contactname="${DD_LETSENCRYPT_EMAIL}" \
	--contactemail="${DD_LETSENCRYPT_EMAIL}"
php admin/cli/maintenance.php --disable
EOF

## Ensure SAML is set up
./dd-ctl saml --no-up

# Proceed further with manual steps
cat <<EOF | tee -a "${DDLOG}"


Proceed now with further manual steps as per:

https://dd.digitalitzacio-democratica.xnet-x.net/docs/post-install.ca/

If necessary, check the install logs at: ${DDLOG}
EOF
