#!/bin/bash
set -eu
### --help Info: Восстановление системы из бэкапа
### --help Info: Перед восстановлением рекомендуем создать бэкап системы. TODO
### --help Usage: eva_restore.sh [--list] <name>
### --help Example: eva_restore.sh --list
### --help Example: eva_restore.sh last_update

. /opt/fox_utils/crab_sys.sh

sys::usage "$@"

declare ARG_1 ARG_LIST
sys::arg_parse "$@"


declare BACKUP_DIR=/opt/var/backup
declare INSTALLATION_TYPE=box
[[ -f /opt/CONFIG ]] && source /opt/CONFIG


do_list() {
	local dir_name
	# shellcheck disable=SC2045
	for dir_name in $(ls "$BACKUP_DIR/"); do
		if [[ -h $BACKUP_DIR/$dir_name ]]; then
			echo "$dir_name -> $(readlink "$BACKUP_DIR/$dir_name")"
		elif [[ -d $BACKUP_DIR/$dir_name ]]; then
			echo "$dir_name"
		fi
	done
	return 0
}


db_list() {
	set -e
	if [[ ${INSTALLATION_TYPE:-box} = box ]]; then
		echo accountdb evadb
	else
		echo evadb
	fi
	return 0
}


check_backup() {
	local backup_dir="$1" db eva_size
	for db in $(db_list); do
		if [[ ! -f $backup_dir/$db.pg ]]; then
			echo "Дамп базы данных $backup_dir/$db.pg отсутствует" >&2
		fi
	done

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


do_restore() {
	local backup_name db backup_dir

	if [[ $1 == */* ]]; then
		backup_dir="$1"
		backup_name="${1##*/}"
	else
		backup_name="$1"
		backup_dir="$BACKUP_DIR/$backup_name"
	fi

	echo "Проверим целостность резервной копии"
	check_backup "$backup_dir"

	echo "Останавливаем сервисы"
	/opt/bin/services stop
	echo "Восстановим файлы системы"
	if [ -d "$backup_dir/eva_root" ]; then
		echo "Обновляю root из $backup_dir"
		rsync --stats --block-size=40507 -c --timeout=60 -a --delete \
			--exclude=/opt --exclude=/dev --exclude=/mnt --exclude=/proc \
			--exclude=/run --exclude=/sys --exclude=/tmp --exclude=/var/log \
			--exclude=/etc/resolv.conf \
			"$backup_dir/eva_root/" /
		# docker монтирует /etc/resolv.conf и его mv падает.
		# Если будет надо можно его руками копировать, но eva_configure его сам поменяет.
	fi

	echo "Обновляю opt из $backup_dir"
	# --exclude=/var: /opt/var/backup /opt/var/log
	rsync --stats --block-size=40507 -c --timeout=60 -a --delete \
		$([[ ! -d $backup_dir/eva_opt/files ]] && echo --exclude=/files) \
		$([[ -d $backup_dir/eva_opt/var/lib ]] && echo --include=/var/lib) \
		--exclude=/var --exclude=/eva-app/backup \
		"$backup_dir/eva_opt/" /opt/
	# TODO if -d "$DIST_DIR/eva_opt/files" sync files

	echo "Восстановим Базы Данных"
	/etc/init.d/postgresql start
	for db in $(db_list); do
		echo "Загрузим БД $db"
		# drop database WITH FORCE - not in v13
		psql -U postgres -c "DROP DATABASE IF EXISTS $db" -c "CREATE DATABASE $db"
		pg_restore -U postgres --clean --if-exists --exit-on-error \
			-d "$db" "$backup_dir/$db.pg"
	done
	/etc/init.d/postgresql stop

	echo "Запускаю сервисы"
	/opt/bin/services stop || true
	/opt/bin/services start

	echo "Применим конфигурацию."
	/opt/bin/eva_configure

	return 0
}


main() {
	if [[ ${ARG_LIST:-} ]]; then
		do_list
		return 0
	fi
	do_restore "$ARG_1"
	return 0
}


main; exit 0  # Защита от изменения скрипта

exit 0
