#!/bin/bash
set -eu
### --help Info: Утилита для создания и очистики бекапов баз данных
### --help Usage: /opt/bin/pg_backup backup|cleanup
### --help Example: /opt/bin/pg_backup backup

. /opt/fox_utils/crab_sys.sh

if [ "${1:---help}" = "--help" ]; then
	sys::usage "$@"
fi

sys::arg_parse "$@"

. /opt/CONFIG

declare INSTALLATION_TYPE
declare -A BACKUP_DIRS
BACKUP_DIRS["evacrmdb"]="/opt/crm/backup"
BACKUP_DIRS["accountdb"]="/opt/account/backup"
CMD="$ARG_1"

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

do_backup() {
	local db backup_name backup_dir tmp_backup_name
	for db in $(db_list); do
		backup_name="${db}_backup.$(date +%Y.%m.%d_%H.%M.%S)"
		tmp_backup_name="tmp__${backup_name}"
		backup_dir="${BACKUP_DIRS[$db]}"
		mkdir -p "$backup_dir"
		echo "Start backup $db"
		if pg_dump -U postgres -Fc -f "$backup_dir/$tmp_backup_name" "$db"; then
			mv "$backup_dir/$tmp_backup_name" "$backup_dir/$backup_name"
			ln -sf "$backup_dir/$backup_name" "$backup_dir/${db}_backup.latest"
			echo "Success backup $backup_dir/$backup_name"
		else
			echo "Error backup $db"
		fi
	done
	return 0
}

do_cleanup() {
	local day week month offset
	local keep_hourly_days=2
	local keep_weekly_weeks=15
	local keep_monthly_month=8
	local keep_daily_days
	local db backup_dir
	for db in $(db_list); do
		backup_dir="${BACKUP_DIRS[$db]}"
		# 2 дня мы храним бэкапы за каждый час (просто не удаляем);
		keep_daily_days="$((30 + keep_hourly_days))"
		# Следующие 30 дней (1 месяц) мы храним 1 бэкап за каждый день;
		for day in $(seq "$keep_hourly_days" "$keep_daily_days"); do
			# sort | tail -n +2 = удаляем все, кроме первого утреннего бэкапа
			# Ну или не утреннего если запустим скрипт не в полночь.
			# В принципе при расчистке запылившихся бэкапов не сильно важно
			find "$backup_dir" -type f -name "${db}_backup.*" \
				-mtime "$day" \
				| sort | tail -n +2 | xargs -r rm -vf
		done
		# Следующие 15 недель (почти 3 месяца) мы храним 1 бэкап за каждую неделю;
		offset=keep_daily_days
		for week in $(seq 1 "$keep_weekly_weeks"); do
			find "$backup_dir" -type f -name "${db}_backup.*" \
				-mtime +$((offset + week * 7)) \
				-mtime -$((offset + (week + 1) * 7)) \
				| sort | tail -n +2 | xargs -r rm -vf
		done
		# Следующие 8 месяцев мы храним 1 бэкап за каждый месяц.
		offset=$((keep_daily_days + (keep_weekly_weeks + 1) * 7))
		for month in $(seq 1 "$keep_monthly_month"); do
			find "$backup_dir" -type f -name "${db}_backup.*" \
				-mtime +$((offset + month * 30)) \
				-mtime -$((offset + (month + 1) * 30)) \
				| sort | tail -n +2 | xargs -r rm -vf
		done
	done
	return 0
}

main() {
	echo "Started $CMD $(date +"%Y-%m-%d %H:%M:%S")"
	"do_${CMD}"
	return 0
}

main "$@"

exit 0
