#!/usr/bin/env bash
#
#   Copyright © 2021,2022 IsardVDI S.L.
#
#   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

OPERATION="$1"

# We need docker-compose >= 1.28 to catch configuration variables
REQUIRED_DOCKER_COMPOSE_VERSION="1.28"

docker_compose_version(){
	docker-compose --version --short | sed 's/^docker-compose version \([^,]\+\),.*$/\1/'
}

check_docker_compose_version(){
	# We cannot use sort -C because is not included in BusyBox v1.33.1 of docker:dind image
	{
		echo "$REQUIRED_DOCKER_COMPOSE_VERSION"
		docker_compose_version
	} | sort -c -V 2> /dev/null
}

get_os(){
	if grep -q ^DISTRIB_ID=Ubuntu /etc/lsb-release 2>/dev/null; then
	   echo ubuntu
	elif [ -f /etc/debian_version ]; then
	   echo debian
	fi
}

help() {
	cat <<-EOF
	 Example: ./dd.ctl [operation] [arguments]

	  For a new installation, you usually will want to run:
	    ./dd-ctl repo-update
	    ./dd-ctl prerequisites
	    ./dd-ctl securize
	    ./dd-ctl all
	    ./dd-ctl saml


	              Generate adminer.yml to access DBs: ./dd-ctl adminer
	                    Bring the current project up: ./dd-ctl all
	              Branding (custom/img, custom/menu): ./dd-ctl branding
	                         Build the compose files: ./dd-ctl build
	                   Build the devel compose files: ./dd-ctl build-devel
	                            Apply customizations: ./dd-ctl customize
	                   Stop the project when started: ./dd-ctl down
   Show external files in repo, their license and source: ./dd-ctl listpatches
Generate .orig and .patch files to compare with upstream: ./dd-ctl genpatches
	                   Rescan nextcloud data folders: ./dd-ctl nextcloud-scan
	      Install all prerequisites for installation: ./dd-ctl prerequisites
	                               Update repository: ./dd-ctl repo-update [branch-name] (defaults to main)
	    Restart api if changes applied (development): ./dd-ctl restart-api
	                        Update SAML certificates: ./dd-ctl saml
	                 Set secure passwords in dd.conf: ./dd-ctl securize
	                Set a config variable in dd.conf: ./dd-ctl setconf VARIABLE [VALUE]
	                  Start the project when stopped: ./dd-ctl up
	                                 Upgrade plugins: ./dd-ctl upgrade-plugins
	         Regenerate docker-compose.yml from conf: ./dd-ctl yml
	EOF
}

# Help messages
if [ -z "$OPERATION" ] || [ "$OPERATION" = "-h" ] || [ "$OPERATION" = "--help" ]; then
    test -n "$OPERATION" || printf "Missing command.\n\n"
    help
    exit
fi

# Sanity checks
if [ -z "$(get_os)" ]; then
	cat >&2 <<-EOF
	*****************************************************************
	Your OS doesn't seem to be Debian or Ubuntu and is not supported!
	Things might still work, please report back.
	*****************************************************************
	EOF
fi
if [ "$OPERATION" != "prerequisites" ]; then
	if [ ! -d "custom" ]; then
		echo "You need to copy custom.sample to custom folder and adapt it to your needs." >&2
		exit 1
	fi
	if [ ! -f "dd.conf" ]; then
		echo "You need to copy dd.conf.sample to dd.conf and adapt" >&2
		exit 1
	fi
	if ! check_docker_compose_version; then
		echo "ERROR: Please use docker-compose greather than or equal to $REQUIRED_DOCKER_COMPOSE_VERSION." >&2
		exit 1
	fi
fi

REPO_BRANCH="${2:-main}"


cp dd.conf .env
CUSTOM_PATH=$(pwd)
. ./.env

prerequisites_docker(){
	# Remove uncompatible docker packages
	for pkg in docker docker-engine docker.io containerd runc; do
		if dpkg -s "${pkg}" >/dev/null; then
			apt-get remove -y "${pkg}"
		fi
	done

	# Install upstream-docker repo pre-requisites
	apt-get install -y \
		apt-transport-https \
		ca-certificates \
		curl \
		gnupg-agent \
		software-properties-common \
		git \
		unzip \
		libffi-dev

	os="$(get_os)"
	curl -fsSL "https://download.docker.com/linux/${os:?}/gpg" | \
		apt-key add -
	add-apt-repository \
		"deb [arch=amd64] https://download.docker.com/linux/${os:?} \
		 $(lsb_release -cs) \
		stable"
	apt-get update -y
	# docker-ce must be used instead of the one from the distro
	apt-get install -y docker-ce docker-ce-cli containerd.io

	apt-get install -y python3-pip
	# docker-compose > 1.28 is required, latest will be installed
	pip3 install docker-compose
}
prerequisites_pwd(){
	apt-get install -y dictionaries-common wamerican
}

update_repo(){
	# Switch to latest version
	git fetch && git checkout $REPO_BRANCH
	# Needed for dd-apps submodules...
	git submodule update --init --recursive
	# Remove old repositories
	for old_dir in isard-apps isard-sso; do
		if [ -d "${old_dir}" ]; then
			mkdir -p _old
			mv "${old_dir}" "_old/${old_dir}_$(date +'%Y-%m-%d_%H-%M')"
		fi
	done
	# Cleanup
	for old_dir in isard-apps isard-sso; do
		git submodule deinit "${old_dir}" || true
		if [ -d "${old_dir}" ]; then
			rmdir "${old_dir}"
		fi
	done
}

build_compose(){
	setconf CUSTOM_PATH "$CUSTOM_PATH" .env
	setconf BUILD_APPS_ROOT_PATH "$CUSTOM_PATH/dd-apps" .env
	setconf BUILD_SSO_ROOT_PATH "$CUSTOM_PATH/dd-sso" .env
	## Prepare apps environment
	ln -sf "${CUSTOM_PATH}/.env" dd-apps/.env
	ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/postgresql && \
	ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/mariadb && \
	ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/moodle && \
	ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/nextcloud && \
	ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/wordpress && \
	ln -sf "${CUSTOM_PATH}/.env" dd-apps/docker/etherpad

	## Prepare sso environment
	ln -sf "${CUSTOM_PATH}/.env" dd-sso/.env
	ln -sf "${CUSTOM_PATH}/.env" dd-sso/docker-compose-parts/.env

	# Clean up older custom data
        rm -rf custom/system/keycloak-themes
	rmdir custom/system 2>/dev/null || true

	if [ "$BEHIND_PROXY" = "true" ]; then
		BEHIND="haproxy-behind.yml"
	else
		BEHIND="haproxy.yml"
	fi

	# Build compose ymls
	docker-compose	-f dd-sso/docker-compose-parts/$BEHIND \
			-f dd-sso/docker-compose-parts/api.yml \
			-f dd-sso/docker-compose-parts/keycloak.yml \
			-f dd-sso/docker-compose-parts/avatars.yml \
			-f dd-apps/docker/postgresql/postgresql.yml \
			-f dd-sso/docker-compose-parts/admin.yml \
								\
			-f dd-apps/docker/moodle/moodle.yml \
			-f dd-apps/docker/nextcloud/nextcloud.yml \
			-f dd-apps/docker/wordpress/wordpress.yml \
			-f dd-apps/docker/etherpad/etherpad.yml \
			-f dd-apps/docker/onlyoffice/onlyoffice.yml \
			-f dd-apps/docker/redis/redis.yml \
			-f dd-apps/docker/postgresql/postgresql.yml \
			-f dd-apps/docker/mariadb/mariadb.yml \
			-f dd-apps/docker/network.yml \
			config > docker-compose.yml
}

listpatches(){
	cat <<-EOM
	# Generate .orig and .patch files with ./dd-ctl genpatches
	# file	license	author	url
	EOM
	for patchfile in $(find . -name 'dd-patch'); do
		patchdir="$(dirname "${patchfile}")"
		grep -vE '^#' "${patchfile}" | awk "{print \"${patchdir}/\" \$0}"
	done
}

genpatches(){
	CD="$(pwd)"
	for patchfile in $(find . -name 'dd-patch'); do
		cd "$(dirname "${patchfile}")"
		echo "IN DIR $(pwd)"
		grep -vE '^#' dd-patch | while IFS= read -r line; do
			fn="$(echo "${line}" | cut -f 1)"
			url="$(echo "${line}" | cut -f 4)"
			wget "${url}" -O "${fn}.orig"
			diff "${fn}.orig" "${fn}" > "${fn}.patch"
		done

		cd "${CD}"
	done
}

build(){
	build_compose
	docker-compose build
}

build_compose_develop(){
	build_compose

	## Prepare sso environment
	setconf CUSTOM_PATH "$CUSTOM_PATH" .env
	setconf BUILD_SSO_ROOT_PATH "$CUSTOM_PATH/dd-sso" .env

	ln -sf "${CUSTOM_PATH}/.env" dd-sso/.env
	ln -sf "${CUSTOM_PATH}/.env" dd-sso/docker-compose-parts/.env

	docker-compose	-f docker-compose.yml \
			-f dd-sso/docker-compose-parts/api.devel.yml \
			-f dd-sso/docker-compose-parts/admin.devel.yml \
			config > devel.yml
}

up(){
	docker-compose up -d
}

down(){
	docker-compose down
}

setup_nextcloud(){
	echo " --> Applying custom settings in nextcloud"
	# docker exec -u www-data dd-apps-nextcloud-app sh -c 'export OC_PASS=$DDADMIN_PASSWORD && php occ user:add --password-from-env --display-name="DD Admin" --group="admin" $DDADMIN_USER'

	# docker exec -u www-data dd-apps-nextcloud-app sh -c 'export OC_PASS=admin && php occ user:delete admin'
	# docker exec -u www-data dd-apps-nextcloud-app sh -c 'export OC_PASS=LostAdminGroup && php occ user:add --password-from-env --display-name="Admin" --group="admin" admin'

	# docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings config:app:set unaprova token --value "SuperS3cret"

	#cp -R $BUILD_APPS_ROOT_PATH/dd-apps/docker/nextcloud/themes/* $DATA_FOLDER/nextcloud/themes/
	docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings config:system:set default_language --value="ca"
	docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings config:system:set skeletondirectory --value=''

	# Disable certain NextCloud apps
	for app in firstrunwizard recommendations dashboard; do
		docker exec -i -u www-data dd-apps-nextcloud-app sh -s <<-EOF
		php occ --no-warnings app:disable "${app}"
		EOF
	done

	# Install and enable NextCloud apps
	for app in bruteforcesettings polls calendar spreed bbb mail ownpad onlyoffice circles; do
		docker exec -i -u www-data dd-apps-nextcloud-app sh -s <<-EOF
		php occ --no-warnings app:install "${app}"
		php occ --no-warnings app:enable "${app}"
		EOF
	done

	# Custom forms
	docker exec dd-apps-nextcloud-app apk add git npm composer
	docker exec -u www-data dd-apps-nextcloud-app rm -rf /var/www/html/custom_apps/forms
	docker exec -u www-data dd-apps-nextcloud-app git clone https://github.com/juanan3ip/form -b dependabot/npm_and_yarn/babel/eslint-parser-7.17.0 /var/www/html/custom_apps/forms
	docker exec -u www-data dd-apps-nextcloud-app npm --prefix /var/www/html/custom_apps/forms install
	docker exec -u www-data dd-apps-nextcloud-app composer -d/var/www/html/custom_apps/forms install --no-dev -o
	docker exec -u www-data dd-apps-nextcloud-app php occ app:enable forms

	# Disable Big Blue Button media check by default
	docker exec -u www-data dd-apps-nextcloud-app php occ config:app:set bbb join.mediaCheck --value="false"
	# Disable Big Blue Button listen only mode by default
	docker exec dd-apps-nextcloud-app sed -i.orig 's/^\(\s*$room->setListenOnly(\)true\();\)$/\1false\2/' /var/www/html/custom_apps/bbb/lib/Service/RoomService.php
	# Enable option to join muted to Big Blue Button room by default
	docker exec dd-apps-nextcloud-app sed -i 's/^\(\s*$room->setJoinMuted(\)false\();\)$/\1true\2/' /var/www/html/custom_apps/bbb/lib/Service/RoomService.php
	# Remove meeting join nextcloud bbb app dialog exclamation marks
	docker exec dd-apps-nextcloud-app sh -c "sed -i.orig 's/\(^\s*\"Please enter your name!\" : [^¡]*\)¡\?\([^!]*\)!\(.*\)$/\1\2\3/' /var/www/html/custom_apps/bbb/l10n/*.json"
	docker exec dd-apps-nextcloud-app sh -c "sed -i 's/\(^\s*\"Let\x27s go!\" : [^¡]*\)¡\?\([^!]*\)!\(.*\)$/\1\2\3/' /var/www/html/custom_apps/bbb/l10n/*.json"

	docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings config:system:set theme  --value=dd
	docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings config:system:set allow_local_remote_servers  --value=true
	docker exec -u www-data dd-apps-nextcloud-app php occ --no-warnings maintenance:theme:update

	#docker exec -u www-data dd-apps-nextcloud-app php occ app:install user_saml
	docker exec -u www-data dd-apps-nextcloud-app php occ app:enable user_saml
	docker exec dd-apps-nextcloud-app apk add jq
	docker exec dd-apps-nextcloud-app sh -c 'jq ". + {\"pad\": [\"application/x-ownpad\"], \"calc\": [\"application/x-ownpad\"]}" /var/www/html/resources/config/mimetypemapping.dist.json > /var/www/html/config/mimetypemapping.json'
	nextcloud_scan
	# Open pads in a new tab/window
	docker exec dd-apps-nextcloud-app sed -i.orig 's/^\(\s*\)\(var viewer = OC.generateUrl.*\)/\1\2\n\1window.open(viewer);\n\1return;/' /var/www/html/custom_apps/ownpad/js/ownpad.js

	# SMTP
	SMTP_LOCAL_PART="$(echo "${SMTP_USER}" | cut -d '@' -f 1)"
	SMTP_DOMAIN="$(echo "${SMTP_USER}" | cut -d '@' -f 2)"
	docker exec -i -u www-data dd-apps-nextcloud-app sh -s <<-EOF
	php occ --no-warnings config:system:set -n mail_smtpmode --value="smtp"
	php occ --no-warnings config:system:set -n mail_smtpsecure --value="${SMTP_PROTOCOL}"
	php occ --no-warnings config:system:set -n mail_sendmailmode --value="smtp"
	php occ --no-warnings config:system:set -n mail_from_address --value="${SMTP_LOCAL_PART}"
	php occ --no-warnings config:system:set -n mail_domain --value="${SMTP_DOMAIN}"
	php occ --no-warnings config:system:set -n mail_smtpauth --value=1
	php occ --no-warnings config:system:set -n mail_smtpauthtype --value="LOGIN"
	php occ --no-warnings config:system:set -n mail_smtphost --value="${SMTP_HOST}"
	php occ --no-warnings config:system:set -n mail_smtpport --value="${SMTP_PORT}"
	php occ --no-warnings config:system:set -n mail_smtpname --value="${SMTP_USER}"
	echo 'Setting Nextcloud password'
	php occ --no-warnings config:system:set -n -q mail_smtppassword --value="${SMTP_PASSWORD}"
	EOF

	# Settings
	docker exec -i -u www-data dd-apps-nextcloud-app sh -s <<-EOF
	php occ --no-warnings config:app:set -n ownpad ownpad_etherpad_enable --value="yes"
	php occ --no-warnings config:app:set -n ownpad ownpad_etherpad_host --value="https://pad.$DOMAIN"

	php occ --no-warnings config:app:set -n onlyoffice DocumentServerUrl --value="https://oof.$DOMAIN"
	php occ --no-warnings config:app:set -n onlyoffice jwt_secret --value="secret"
	php occ --no-warnings config:app:set -n onlyoffice jwt_header --value="Authorization"
	php occ --no-warnings config:app:set -n onlyoffice sameTab --value="false"

	# Moodle nextcloud task needs forcesave onlyoffice option
	php occ --no-warnings config:app:set -n onlyoffice customizationForcesave --value="true"

	# Enable circles
	php occ --no-warnings config:app:set -n circles members_limit --value="150"
	php occ --no-warnings config:app:set -n circles allow_linked_groups --value="1"
	php occ --no-warnings config:app:set -n circles skip_invitation_to_closed_circles --value="1"

	# Add allow list IPs
	php occ --no-warnings config:app:set -n bruteForce whitelist_1 --value='172.16.0.0/12'

	# OnlyOffice
	php occ --no-warnings config:app:set -n onlyoffice preview --value="true"
	php occ --no-warnings config:app:set -n onlyoffice defFormats --value="{\"csv\":\"false\",\"doc\":\"true\",\"docm\":\"false\",\"docx\":\"true\",\"docxf\":\"true\",\"oform\":\"true\",\"dotx\":\"false\",\"epub\":\"false\",\"html\":\"false\",\"odp\":\"true\",\"ods\":\"true\",\"odt\":\"true\",\"otp\":\"true\",\"ots\":\"true\",\"ott\":\"true\",\"pdf\":\"false\",\"potm\":\"false\",\"potx\":\"false\",\"ppsm\":\"false\",\"ppsx\":\"true\",\"ppt\":\"true\",\"pptm\":\"false\",\"pptx\":\"true\",\"rtf\":\"false\",\"txt\":\"false\",\"xls\":\"true\",\"xlsm\":\"false\",\"xlsx\":\"true\",\"xltm\":\"false\",\"xltx\":\"true\"}",
        php occ --no-warnings config:app:set -n onlyoffice editFormats --value="{\"csv\":\"true\",\"odp\":\"false\",\"ods\":\"false\",\"odt\":\"false\",\"rtf\":\"false\",\"txt\":\"true\"}"

	EOF

	# Allow nextcloud into other apps iframes
	# Content-Security-Policy: frame-ancestors 'self' *.$DOMAIN;
	docker exec dd-apps-nextcloud-app sed -i -e "/protected \\\$allowedFrameAncestors = \[/{n;s/\('\\\\\'self\\\\\'\)\('\)/\1 *.$DOMAIN\2/}" /var/www/html/lib/public/AppFramework/Http/ContentSecurityPolicy.php

	# Content-Sety-Policy: connect-src 'self -' *.$DOMAIN;
	docker exec dd-apps-nextcloud-app sed -i -e "/protected \\\$allowedConnectDomains = \[/{n;s/\('\\\\\'self\\\\\'\)\('\)/\1 *.$DOMAIN\2/}" /var/www/html/lib/public/AppFramework/Http/ContentSecurityPolicy.php

	# Content-Sety-Policy: img-src 'self' *. -$DOMAIN;
	docker exec dd-apps-nextcloud-app sed -i -e "/protected \\\$allowedImageDomains = \[/{n;s/\('\\\\\'self\\\\\'\)\('\)/\1 *.$DOMAIN\2/}" /var/www/html/lib/public/AppFramework/Http/ContentSecurityPolicy.php

	# Content-Sety-Policy: style-src 'self'  -*.$DOMAIN;
	docker exec dd-apps-nextcloud-app sed -i -e "/protected \\\$allowedStyleDomains = \[/{n;s/\('\\\\\'self\\\\\'\)\('\)/\1 *.$DOMAIN\2/}" /var/www/html/lib/public/AppFramework/Http/ContentSecurityPolicy.php

	# Content-Sety-Policy: font-src 'self' * -.$DOMAIN;
	docker exec dd-apps-nextcloud-app sed -i -e "/protected \\\$allowedFontDomains = \[/{n;s/\('\\\\\'self\\\\\'\)\('\)/\1 *.$DOMAIN\2/}" /var/www/html/lib/public/AppFramework/Http/ContentSecurityPolicy.php

	# Fix nextcloud files_external "segudos" typo
	# https://github.com/nextcloud/server/pull/28990
	docker exec dd-apps-nextcloud-app sh -c 'sed -i.orig -e "s/segudos/segundos/" /var/www/html/apps/files_external/l10n/es_*.js'

	# Import fix from Nextcloud 22 of pdf viewer
	# https://github.com/nextcloud/files_pdfviewer/issues/381#issuecomment-845806364
	docker exec dd-apps-nextcloud-app sed -i 's/encodeURIComponent(i\[a\])/i[a]/' /var/www/html/apps/files_pdfviewer/js/files_pdfviewer-main.js

	# Add default file for moodle activities
	if [ ! -f $DATA_FOLDER/nextcloud/admin/files/template.docx ]; then
		cp dd-apps/docker/nextcloud/template.docx $DATA_FOLDER/nextcloud/admin/files/
		nextcloud_scan
	fi

	configure_nextcloud_logo
}

nextcloud_scan(){
	# The folders shown as 'not writeable' are empty user folders. Not a problem.
	docker exec -u www-data dd-apps-nextcloud-app php occ files:scan --all
}

setup_moodle(){
	echo " --> Applying custom settings in moodle"
	docker exec -ti dd-apps-moodle php7 admin/cli/cfg.php --name=guestloginbutton --set=0
	docker exec -ti dd-apps-moodle php7 admin/cli/cfg.php --name=enrol_plugins_enabled --set=manual
	docker exec -ti dd-apps-moodle php7 admin/cli/cfg.php --name=enablemobilewebservice --set=0
	docker exec -ti dd-apps-moodle php7 admin/cli/cfg.php --name=enablebadges --set=0
	docker exec -ti dd-apps-moodle php7 admin/cli/cfg.php --name=timezone --set="${MOODLE_TIMEZONE-Europe/Madrid}"
	docker exec -ti dd-apps-moodle php7 admin/cli/purge_caches.php
}

setup_wordpress(){
	echo " --> Applying custom settings in wordpress"
	## Multisite
	docker exec -ti dd-apps-wordpress /bin/sh -c "/multisite.sh"

	docker-compose run --user=33 dd-apps-wordpress-cli /bin/bash -s <<-EOF
	wp plugin activate onelogin-saml-sso
	wp plugin install generateblocks --activate
	wp plugin activate generateblocks --network

	wp theme install generatepress --activate
	wp theme enable generatepress --network
	wp theme delete twentynineteen
	wp theme delete twentytwenty
	wp theme delete twentytwentyone

	wp option set WPLANG ca
	wp option set date_format "d/m/Y"
	EOF
	docker-compose run --user=root dd-apps-wordpress-cli /bin/bash -c 'chown -R 33:33 /var/www/html/wp-content/uploads;'
}

setup_keycloak(){
	# configure keycloak: realm and client_scopes
	echo " --> Setting up SAML for moodle"
	docker exec -ti dd-sso-admin sh -c "export PYTHONWARNINGS='ignore:Unverified HTTPS request' && cd /admin/saml_scripts/ && python3 keycloak_config.py"
}

saml_certificates(){
	wait_for_moodle
	echo " --> Setting up SAML for moodle"
	docker exec -ti dd-sso-admin sh -c "export PYTHONWARNINGS='ignore:Unverified HTTPS request' && cd /admin/saml_scripts/ && python3 moodle_saml.py"
	docker exec -ti dd-apps-moodle php7 admin/cli/purge_caches.php

	# CERTIFICATES FOR SAML
	echo " --> Generating certificates for nextcloud and wordpress"
	docker exec -ti dd-sso-admin /bin/sh -c "/admin/generate_certificates.sh"

	# SAML PLUGIN NEXTCLOUD
	echo " --> Setting up SAML for nextcloud"
	docker exec -ti dd-sso-admin sh -c "export PYTHONWARNINGS='ignore:Unverified HTTPS request' && cd /admin/saml_scripts/ && python3 nextcloud_saml.py"

	# SAML PLUGIN WORDPRESS
	echo " --> Setting up SAML for wordpress"
	docker exec -ti dd-sso-admin sh -c "export PYTHONWARNINGS='ignore:Unverified HTTPS request' && cd /admin/saml_scripts/ && python3 wordpress_saml.py"

	# SAML PLUGIN EMAIL
	echo " --> Setting up SAML for email"
	docker exec -ti dd-sso-admin sh -c "export PYTHONWARNINGS='ignore:Unverified HTTPS request' && cd /admin/saml_scripts/ && python3 email_saml.py"
}

wait_for_moodle(){
	echo "Waiting for system to be fully up before customizing... It can take some minutes..."
	echo " (you can monitorize install with: docker logs dd-apps-moodle --follow"
	while [ "`docker inspect -f {{.State.Health.Status}} dd-apps-moodle`" != "healthy" ]; do     sleep 2; done
}

upgrade_moodle(){
	docker exec -ti dd-apps-moodle php7 admin/cli/maintenance.php --enable
	docker exec -ti dd-apps-moodle php7 admin/cli/upgrade.php --non-interactive --allow-unstable
	docker exec -ti dd-apps-moodle php7 admin/cli/maintenance.php --disable
}

extras_adminer(){
	docker-compose 	-f dd-apps/docker/network.yml \
					-f dd-sso/docker-compose-parts/adminer.yml config > adminer.yml
	echo " --> Generated adminer.yml"
	echo "     Bring it up: docker-compose -f adminer.yml up -d"
	echo "     Connect to: https://sso.$DOMAIN/dd-sso-adminer/"
	echo "     Parameters:"
	echo "       - System: PostgreSQL (or Mysql for wordpress db)"
	echo "         Server: dd-apps-postgresql (or dd-apps-mariadb for wordpress db)"
	echo "         User/Pass/Database from dd.conf"
}

extras_pgtuner(){
	docker-compose  -f dd-apps/docker/network.yml \
					-f dd-sso/docker-compose-parts/pgtuner.yml config > pgtuner.yml
	echo " --> Generated pgtuner.yml"
}

extras_nextcloud_remove_banned_ips(){
	docker-compose exec dd-apps-postgresql psql -v ON_ERROR_STOP=1 \
						-U admin nextcloud -c "DELETE FROM oc_bruteforce_attempts;"
}

extras_nextcloud_set_admin_group(){
	docker exec -u www-data dd-apps-nextcloud-app sh -c 'export OC_PASS=admin && php occ user:delete admin'
	docker exec -u www-data dd-apps-nextcloud-app sh -c 'export OC_PASS=N3xtcl0ud && php occ user:add --password-from-env --display-name="Admin" --group="admin" admin'
}

extras_dump_keycloak_client(){
	docker exec -ti dd-sso-keycloak sh -c " 
	/opt/jboss/keycloak/bin/kcadm.sh config credentials --server http://localhost:8080/auth --realm master --user admin --password keycloakkeycloak \
	&& /opt/jboss/keycloak/bin/kcadm.sh get clients/bef873f0-2079-4876-8657-067de27d01b7 -r master"""
}
upgrade_plugins_moodle(){
	wait_for_moodle
	rm -rf /tmp/moodle

	mkdir -p /tmp/moodle/mod
	mkdir -p /tmp/moodle/mod/assign/submission
	mkdir -p /tmp/moodle/auth/saml2
	mkdir -p /tmp/moodle/theme/cbe
	mkdir -p /tmp/moodle/blocks

    curl --location $MOODLE_PLUGIN_JITSI > jitsi.zip
    unzip jitsi.zip -d /tmp/moodle/mod/
    rm jitsi.zip

    curl --location $MOODLE_PLUGIN_BBB > bbb.zip
    unzip bbb.zip -d /tmp/moodle/mod/
    rm bbb.zip

    # curl --location https://github.com/isard-vdi/moodle-auth_saml2/archive/refs/heads/role_map.zip > auth_saml2.zip
	# curl --location https://moodle.org/plugins/download.php/24556/auth_saml2_moodle311_2021062900.zip > auth_saml2.zip
	curl --location $MOODLE_PLUGIN_SAML > auth_saml2.zip
    unzip auth_saml2.zip -d /tmp/moodle/auth/
    mv /tmp/moodle/auth/moodle-auth_saml2-role_map/* /tmp/moodle/auth/saml2/
    rm -rf /tmp/moodle/auth/moodle-auth_saml2-role_map
    rm auth_saml2.zip

	if [[ "$MOODLE_PLUGIN_TRESIPUNTSHARE" == *"develop"* ]]; then
		PLUGIN_BRANCH=develop
	else
		PLUGIN_BRANCH=master
	fi
    curl --location $MOODLE_PLUGIN_TRESIPUNTSHARE > tresipuntshare.zip
    unzip tresipuntshare.zip -d /tmp/moodle/mod/
    mv /tmp/moodle/mod/moodle_mod_tresipuntshare-$PLUGIN_BRANCH /tmp/moodle/mod/tresipuntshare
    rm tresipuntshare.zip

	if [[ "$MOODLE_PLUGIN_TRESIPUNTVIDEO" == *"develop"* ]]; then
		PLUGIN_BRANCH=develop
	else
		PLUGIN_BRANCH=master
	fi
    curl --location $MOODLE_PLUGIN_TRESIPUNTVIDEO > tresipuntvideo.zip
    unzip tresipuntvideo.zip -d /tmp/moodle/mod/
    mv /tmp/moodle/mod/moodle_mod_tresipuntvideo-$PLUGIN_BRANCH /tmp/moodle/mod/tresipuntvideo
    rm tresipuntvideo.zip

	if [[ "$MOODLE_PLUGIN_TRESIPUNTAUDIO" == *"develop"* ]]; then
		PLUGIN_BRANCH=develop
	else
		PLUGIN_BRANCH=master
	fi
    curl --location $MOODLE_PLUGIN_TRESIPUNTAUDIO > tresipuntaudio.zip
    unzip tresipuntaudio.zip -d /tmp/moodle/mod/
    mv /tmp/moodle/mod/moodle_mod_tresipuntaudio-$PLUGIN_BRANCH /tmp/moodle/mod/tresipuntaudio
    rm tresipuntaudio.zip

	if [[ "$MOODLE_PLUGIN_ASSIGNSUBMISSION" == *"develop"* ]]; then
		PLUGIN_BRANCH=develop
	else
		PLUGIN_BRANCH=master
	fi
    curl --location $MOODLE_PLUGIN_ASSIGNSUBMISSION > assignsubmission_tipnc.zip
    unzip assignsubmission_tipnc.zip -d /tmp/moodle/mod/assign/submission/
    mv /tmp/moodle/mod/assign/submission/moodle_assignsubmission_tipnc-$PLUGIN_BRANCH /tmp/moodle/mod/assign/submission/tipnc
    rm assignsubmission_tipnc.zip

    curl --location $MOODLE_PLUGIN_TRESIPUNTMODSPEND > block_tresipuntmodspend.zip
    unzip block_tresipuntmodspend.zip -d /tmp/moodle/blocks/
    rm block_tresipuntmodspend.zip

	if [[ "$MOODLE_THEME_CBE" == *"develop"* ]]; then
		PLUGIN_BRANCH=develop
	else
		PLUGIN_BRANCH=master
	fi
    curl --location $MOODLE_THEME_CBE > tresipunt_theme_cbe.zip
    unzip tresipunt_theme_cbe.zip -d /tmp/moodle/theme/cbe/
    mv /tmp/moodle/theme/cbe/moodle_theme_cbe-$PLUGIN_BRANCH/* /tmp/moodle/theme/cbe/
    rm tresipunt_theme_cbe.zip

    #mkdir -p /tmp/moodle/local/tresipuntimportgc
    #cp -R local_plugins/moodle/tresipuntimportgc/* /tmp/moodle/local/tresipuntimportgc/

	cp -R /tmp/moodle/* $SRC_FOLDER/moodle/
	rm -rf /tmp/moodle
	docker exec -ti dd-apps-moodle php7 admin/cli/purge_caches.php
}

upgrade_plugins_nextcloud(){
        wget https://code.jquery.com/jquery-3.2.1.slim.min.js -O $SRC_FOLDER/nextcloud/themes/dd/core/js/jquery_slim_3.2.1.js
	cp -R dd-apps/docker/nextcloud/src/* $SRC_FOLDER/nextcloud/
}

upgrade_plugins_wp(){
	cp -R dd-apps/docker/wordpress/src/* $SRC_FOLDER/wordpress/

	if [ ! -d $SRC_FOLDER/wordpress/wp-content/mu-plugins ]; then
		git clone https://gitlab.com/muplugins-multiste1/muplugins-google-sites.git $SRC_FOLDER/wordpress/wp-content/mu-plugins
	fi
	if [ ! -d $SRC_FOLDER/wordpress/wp-content/mu-plugins/.git ]; then
		echo "WARNING: $SRC_FOLDER/wordpress/wp-content/mu-plugins is not a git repository."
		echo "         This could be due to old installation. To bring all new mu-plugins code for WP"
		echo "         remove that folder and it will be cloned and mantained with git from now on."
	else
		sh -c "cd $SRC_FOLDER/wordpress/wp-content/mu-plugins; git pull"
	fi
	docker-compose run --user=root dd-apps-wordpress-cli /bin/bash -c 'chown -R 33:33 /var/www/html/wp-content/mu-plugins;'
}

update_logos_and_menu(){
	# docker exec -ti dd-sso-keycloak sh -c "/opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheThemes,value=false)'"
	# docker exec -ti dd-sso-keycloak sh -c "/opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='/subsystem=keycloak-server/theme=defaults/:write-attribute(name=cacheTemplates,value=false)'"
	# docker exec -ti dd-sso-keycloak sh -c "/opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='/subsystem=keycloak-server/theme=defaults/:write-attribute(name=staticMaxAge,value=-1)'"
	# docker exec -ti dd-sso-keycloak sh -c "/opt/jboss/keycloak/bin/jboss-cli.sh --connect --command='reload'"
	docker exec -ti --user root dd-sso-keycloak sh -c 'rm -rf /opt/jboss/keycloak/standalone/tmp/kc-gzip-cache/*'
	docker-compose build dd-sso-api && docker-compose up -d dd-sso-api
	configure_nextcloud_logo
}

configure_nextcloud_logo(){
	local instance_id=$(docker exec -u www-data dd-apps-nextcloud-app php occ config:system:get instanceid)
	local cachebuster=$(docker exec -u www-data dd-apps-nextcloud-app php occ config:app:get theming cachebuster)
	docker exec -u www-data dd-apps-nextcloud-app mkdir -p /var/www/html/data/appdata_$instance_id/theming/images
	docker cp custom/img/logo.png dd-apps-nextcloud-app:/var/www/html/data/appdata_$instance_id/theming/images/logo
	docker cp custom/img/background.png dd-apps-nextcloud-app:/var/www/html/data/appdata_$instance_id/theming/images/background
	docker exec dd-apps-nextcloud-app chown www-data:www-data /var/www/html/data/appdata_$instance_id/theming/images/{logo,background}
	docker exec -u www-data dd-apps-nextcloud-app php occ config:app:set theming logoMime --value="image/png"
	docker exec -u www-data dd-apps-nextcloud-app php occ config:app:set theming backgroundMime --value="image/png"
	docker exec -u www-data dd-apps-nextcloud-app php occ config:app:set theming cachebuster --value="$(expr $cachebuster + 1 )"
}

genpwd() {
	if [ ! -f /usr/share/dict/words ]; then
		prerequisites_pwd > /dev/null
	fi
	shuf -n3 /usr/share/dict/words | tr -d "\n" | tr -d "'"
}

securize() {
	for dd_var in \
			ADMINAPP_PASSWORD \
			DDADMIN_PASSWORD \
			KEYCLOAK_PASSWORD \
			KEYCLOAK_DB_PASSWORD \
			POSTGRES_PASSWORD \
			MARIADB_PASSWORD \
			MOODLE_POSTGRES_PASSWORD \
			MOODLE_ADMIN_PASSWORD \
			NEXTCLOUD_POSTGRES_PASSWORD \
			NEXTCLOUD_ADMIN_PASSWORD \
			ETHERPAD_POSTGRES_PASSWORD \
			ETHERPAD_ADMIN_PASSWORD \
			WORDPRESS_MARIADB_PASSWORD \
			WORDPRESS_ADMIN_PASSWORD \
			IPA_ADMIN_PWD; do
		setconf "${dd_var}" "$(genpwd)"
	done
}

setconf() {
	dd_var="$(echo "$1" | tr "[:lower:]" "[:upper:]")"
	dd_val="$2"
	dd_line="$(printf '%s="%s"' "${dd_var:?}" "${dd_val}")"
	conf_file="${3:-dd.conf}"
	if grep -qE "^${dd_var:?}=" "${conf_file}"; then
		# Found uncommented, replace in-place
		sed -i'' -E "s!^${dd_var:?}=.*\$!${dd_line}!" "${conf_file}"
	elif grep -qE "^#[[:space:]]*${dd_var:?}=" "${conf_file}"; then
		# Found commented, replace in-place
		sed -i'' -E "s!^#[[:space:]]*${dd_var:?}=.*\$!${dd_line}!" "${conf_file}"
	else
		# Not found, append
		echo "${dd_line}" >> "${conf_file}"
	fi
}

# Argument handling
case "$OPERATION" in
	build)
		build
	;;
	build-devel)
		build_compose_develop
	;;
	adminer)
		extras_adminer
	;;
	all)
		build
		up

		wait_for_moodle
		upgrade_plugins_moodle
		upgrade_plugins_nextcloud
		upgrade_plugins_wp

		setup_nextcloud
		setup_moodle
		setup_wordpress

		setup_keycloak
		saml_certificates

		cat <<-EOF

		 #### After install ####
		 - SSO in moodle should be active. You can go to: https://moodle.$DOMAIN
		   If it fails, regenerate and lock certificate in moodle SAML2 connector as a local admin.
		   After that run ./dd-ctl saml
		 - SSO in nextcloud should be active. You can go to: https://nextcloud.$DOMAIN
		 - SSO in wordpress should be active. You should go to https://wp.$DOMAIN/wp-admin//plugins.php

		 #### Update customizations ####
		 - ./dd-ctl customize
		EOF
	;;
	branding)
		up
		wait_for_moodle
		update_logos_and_menu
	;;
	customize)
		up
		wait_for_moodle
		setup_nextcloud
		setup_wordpress
		setup_moodle
	;;
	down)
		down
	;;
	nextcloud-scan)
		nextcloud_scan
	;;
	pgtuner)
		extras_pgtuner
	;;
	prerequisites)
		prerequisites_docker
		prerequisites_pwd
	;;
	repo-update)
		update_repo
	;;
	reset-data|reset-1714)
		cat <<-EOF
		# Following commands RESET ALL DATA except for certificates
		# execute them only if you know what you are doing
		# This *will* result in DATA LOSS
		 "$0" down
		 rm -rf /opt/DD/data/*
		 rm -rf /opt/DD/db/*
		 rm -rf '$SRC_FOLDER/avatars'
		 rm -rf '$SRC_FOLDER/moodle'
		 rm -rf '$SRC_FOLDER/nextcloud'
		 rm -rf '$SRC_FOLDER/wordpress'
		EOF
	;;
	restart-api)
		up
		wait_for_moodle
		docker restart dd-sso-api
	;;
	saml)
		up
		wait_for_moodle
		setup_keycloak
		saml_certificates
	;;
	securize)
		securize
	;;
	setconf)
		setconf "$2" "$3"
	;;
	up)
		up
	;;
	upgrade-plugins)
		up
		wait_for_moodle
		upgrade_plugins_moodle
		upgrade_plugins_nextcloud
		upgrade_plugins_wp
	;;
	yml)
		cp dd.conf .env
		CUSTOM_PATH=$(pwd)
		. ./.env
		build_compose
	;;
	listpatches)
		listpatches
	;;
	genpatches)
		genpatches
	;;
	*)
		printf "Unknown command '%s'\n\n" "$OPERATION" >&2
		help >&2
		exit 1
	;;
esac