#!/bin/bash
set -eu
echo "$0 $@ [$$] START" >&2

set -x

if [[ ${1:-} != install && ${1:-} != setup ]]; then
	echo "Info: !!! НЕ не запускайте, если не знаете что делаете"
	echo "Info: Скрипт заменяет / системы, дистрибутивом EvaTeam"
	echo "Info: Предназначен для инициализации образа VM в Cloud режиме"
	echo "Usage: $0 install|setup [distr_dir]"
	echo "Usage: install - защита от нежелательного запуска"
	echo "Usage: setup - продолжение установки"
	echo "Usage: distr_dir - расположение дистрибутива, по-умолчанию папка запуска."
	echo "Example: /mnt/evateam/public/official/devel/last/eva_opt/bin/_vm_install.sh install"
	[[ ${1:-} == --help ]] && exit 0
	exit 1
fi

declare COMMAND="$1"

if pidof -csxo %PPID "${0##*/}"; then
	echo "Already running" >&2
	exit 1
fi

# TODO: может какую защиту, чтобы работало только на новой ВМ.
declare DIST_DIR

if [[ ${2:-} ]]; then
	DIST_DIR="$2"
else
	DIST_DIR="$( cd -- "${0%/*}" &>/dev/null && pwd -P )"
	if [[ $DIST_DIR != */eva_opt/bin ]]; then
		echo "Не могу определить путь к дистрибутиву. Укажите его явно параметром" >&2
		exit 1
	fi
	DIST_DIR="${DIST_DIR%/eva_opt/bin}"
fi


check_distr() {
	local eva_size check_file

	for check_file in branch eva_opt eva_root eva_opt.version eva_opt/eva_version; do
		if [[ ! -e $DIST_DIR/$check_file ]]; then
			echo "Отсутствует $DIST_DIR/$check_file." \
				"Вероятно дистрибутив неисправен." >&2
			exit 1
		fi
	done

	set -o pipefail
	eva_size="$(du -s "$DIST_DIR/eva_opt" | awk '{print $1}')"
	set +o pipefail
	# Меньше 100Мб
	if [[ $eva_size -lt 100000 ]]; then
		echo "Ошибка обновления! Размер opt меньше 100Мб. $DIST_DIR" >&2
		exit 1
	fi
	set -o pipefail
	eva_size="$(du -s "$DIST_DIR/eva_root" | awk '{print $1}')"
	set +o pipefail
	# Меньше 2Гб
	if [[ $eva_size -lt 2000000 ]]; then
		echo "Ошибка обновления! Размер root меньше 2Гб. $DIST_DIR" >&2
		exit 1
	fi
	return 0
}


install_files() {
	rsync --exclude=/CONFIG --exclude=/files/* --exclude=/files.meta/* \
		--exclude=/eva-app/common/static/forms/* --exclude=/eva-app/backup/* \
		--stats --checksum -a --delete \
		"$DIST_DIR/eva_opt/" /opt/
	rsync  --exclude=/dev --exclude=/mnt --exclude=/proc --exclude=/sys --exclude=/tmp \
		--include=/run/postgresql --include=/run/redis --exclude=/run/** \
		--exclude=/opt \
		--exclude=/etc/hostname --exclude=/etc/hosts --exclude=/etc/resolv.conf \
		--stats --checksum -a --delete \
		"$DIST_DIR/eva_root/" /
	return 0
}


install_config() {
	# TODO: не копировать custom из distr, а лучше не копировать кастом в distr.
	cat /dev/null > /opt/eva-app/custom/config.py
	cat /dev/null > /opt/rdisk/rdisk/custom/config.py
	# Для совместимости, у старых ВМ создаётся, но вроде не используется.
	echo evateam.ru > /opt/eva-app/custom/cloud_name

	cat > /opt/CONFIG <<EOF
# Домен EvaTeam
DOMAIN=""
# Email администратора
ADMIN_EMAIL=""

# Получать бесплатный SSL-сертификат от Lets Encrypt
NGINX_USE_CERTBOT="0"

# Параметры системы обновления
UPDATE_SERVER=""
UPDATE_BRANCH="$(cat "$DIST_DIR/branch")"

UPDATE_URL="/mnt"
INSTALLATION_TYPE=cloud
EOF
	return 0
}


install_jwt() {
	rm -f /opt/account/jwt_rsa{,.pub}
	rm -f /opt/account/custom/jwt_rsa{,.pub}
	rm -f /opt/eva-app/jwt_rsa{,.pub}
	rm -f /opt/eva-app/custom/jwt_rsa{,.pub}
	# TODO: Может его в /mnt/подкладывать вместо хардкода?
	cat > /opt/account/custom/jwt_rsa.pub <<EOF
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCv0irpUhO5+NaG352pK+ZSyUWG
oRK7m6YzMnNy69zgXMbKC6gdEaPhAiEKCEOOc9Wrbrcb9Pj+j8p2abujxRssS4H+
7QHDuONY9bp+g0FGFCxy72XyAluNhL/KLhkRSuSUhHQfQd8YVG0FXVl9pNpahALa
FLOsqCAfIWV6oLPcIQIDAQAB
-----END PUBLIC KEY-----
EOF
	ln -s custom/jwt_rsa.pub /opt/account/jwt_rsa.pub
	(
		cd /opt/eva-app
		python3 manage.py generate_rsa_keypair
	)
	mv /opt/eva-app/jwt_rsa{,.pub} /opt/eva-app/custom/
	ln -s custom/jwt_rsa /opt/eva-app/jwt_rsa
	ln -s ../account/jwt_rsa.pub /opt/eva-app/jwt_rsa.pub
	return 0
}


install_db() {
	# DB create and init
	psql -U postgres -c "DROP DATABASE evadb;"
	psql -U postgres -c "CREATE DATABASE evadb;"
	(
		cd /opt/eva-app
		python3 manage.py init_db
		# init_db:rdisk use rsa_public_key!!!
		# /opt/eva_deploy/docker/alembic_tag.py
		python3 <<EOF
import alembic.config
import alembic.command
alembic.command.stamp(alembic.config.Config("./alembic.ini"), "head")
EOF
		# Вызов патча сохраняет последний патч в БД, аналог alembic_tag
		python3 manage.py patch

		# init default admin and company
		python3 -m bin.default_data
		if python3 manage.py init_demo_data --email "default.admin@crm.evacrm.ru" \
			&> /init_demodata.log; then
			echo "Init Demo data log wc: $(wc /init_demodata.log)"
			rm /init_demodata.log
		else
			echo "Init Demo data error(/init_demodata.log)"
			tail -n 1000 /init_demodata.log
			return 1
		fi
	)
	return 0
}


do_install() {
	check_distr
	install_files
	install_config
	return 0
}


do_setup() {
	install_jwt
	install_db
	return 0
}


main() {
	if [[ $COMMAND == install ]]; then
		do_install
		echo "Install complete please do 'reboot -f' to restart system "
	elif [[ $COMMAND == setup ]]; then
		systemctl stop evateam
		sleep 5
		systemctl start redis-server postgresql
		do_setup
		/opt/bin/eva_configure
	fi
	return 0
}


main


echo "$0 $@ [$$] SUCCESS" >&2
exit 0
