#!/bin/bash

set -eu

. /opt/fox_utils/crab_sys.sh
[ "${1:---help}" = "--help" ] && sys::usage "$@"
### --help Info: удаление бекапа старше определенного числа дней
### --help Usage: vz7_cli backup-del $VM_NAME [--older-than-days=30] [--all] [--clean-trash]
### --help Example:
sys::arg_parse "$@"

declare VM_NODE_BACKUP NODE_IP PLOOP_BACKUP PLOOP_PRIVATE

if [ -z "$ARG_1" ]; then
	echo "Не указана VM для удаления бекапов"
	exit 255
fi

. /opt/fox_utils/fox_conf vm get "$ARG_1"

if [ "$VM_TYPE" = "vz7" ]; then
	PLOOP_NAME="$VM_NAME"
	PLOOP_PRIVATE="$VM_DISK"
elif [ "$VM_TYPE" = "kvm" ]; then
	PLOOP_NAME="kvm-$VM_NAME"
	PLOOP_PRIVATE="${VM_DISK/root/private}"
else
	echo "LOG_ERROR Не поддерживается тип $VM_TYPE" >&2
	exit 255
fi
PLOOP_BACKUP="/vz/backup/$PLOOP_NAME/disk"

__ssh(){
	/opt/fox_utils/crab_ssh "$@" </dev/null;
	return 0
}

# TODO проверять список в /vz/private/$VM_NAME/.INFO/
# или на бекап ноде /vz/backup/$VM_NAME/.BACKUP/
# после миграции старые бекапы попадают на VM_NODE_LOCATION
/opt/fox_vz7/vz7_backup-list "$ARG_1" > /tmp/vz7_backup-del.$$

if [ ! -s /tmp/vz7_backup-del.$$ ];then
	echo "Нет бекапов для удаления"
	rm -f /tmp/vz7_backup-del.$$
	exit 0
fi

__exists_backup_on_node(){
	set -e
	local node_ip="$1"
	__ssh "$node_ip" "[ -d "$PLOOP_BACKUP" ] && echo TRUE || echo FALSE"
	return 0
}

__delete_removed_files(){
	local backup_id="$1"
	local node_ip="$2"
	local line file_name backup_file_dir
	# crab_sync сохраняет все переданные файлы в /.INFO/$backup_id/file.list и копируется в /.BACKUP/
	# Пока алгоритм удаления такой, смотрим список файлов у бекапа и проверяем наличие этих файлов
	# в списках у других бекапов, если файла в них нет, то его можно уже удалить.
	# todo эти файлы должен удалять crab_sync
	while read -r line; do
		if ! grep -q -r --exclude-dir="$backup_id" "$line" "$PLOOP_PRIVATE/.BACKUP/"; then
			# Удаляем сам файл и чистим .BMAP
			backup_file_dir="${line/$PLOOP_PRIVATE/$PLOOP_BACKUP}"
			backup_file_dir="${backup_file_dir%/*}"
			file_name="${line##*/}"
			__ssh "$node_ip" "rm -f "${backup_file_dir}/.BMAP/${file_name}"* "\
				""${backup_file_dir}/${file_name}""
		fi
	done < "$PLOOP_PRIVATE/.BACKUP/$backup_id/file.list"
	return 0
}

delete_backup_by_id(){
	local backup_id="$1"
	if [ "$(wc -l < /tmp/vz7_backup-del.$$)" = "1" ]; then
		echo "WARNING Остался последний бекап $backup_id"
		return 0
	fi
	# Бекап может быть локальный, на бекап-ноде, на другой ноде
	# в обычном случае это будет последний ip в vz7_backup-list
	# но возможно бекап был перенесен на бекап-ноду
	# поэтому на всякий случай проверим дважды по сохраненному ip
	# и через VM_NODE_BACKUP
	local node_ip="$(grep "$backup_id" /tmp/vz7_backup-del.$$)"
	node_ip=${node_ip##* }
	node_ip="${node_ip%%/*}"
	if [ "$(__exists_backup_on_node "$node_ip")" = FALSE ]; then
		if [ -f "/opt/fox_conf/node/${VM_NODE_BACKUP}/node.conf" ]; then
			node_ip=$( . "/opt/fox_conf/node/${VM_NODE_BACKUP}/node.conf"; echo $NODE_IP; )
		fi
	fi
	if [ "$(__exists_backup_on_node "$node_ip")" = FALSE ]; then
		echo "На ноде не найден бекап $backup_id"
		rm -f /tmp/vz7_backup-del.$$
		exit 255
	fi
	echo "Удаляем бекап $backup_id"
	__delete_removed_files "$backup_id" "$node_ip"
	# удаляем бекап из папок .BLOG .INFO
	__ssh "$node_ip" "rm -rf --one-file-system "\
		"\$(find "$PLOOP_BACKUP" -type d -name "$backup_id" -path "*/.BLOG/*") "\
		""$PLOOP_BACKUP/.INFO/$backup_id""
	# удаляем бекап из списка бэкапов
	rm -rf --one-file-system "${PLOOP_PRIVATE}/.BACKUP/${backup_id}"
	# удалим из текущего списка бекапов чтобы всегда оставлять 1 бекап
	sed -i "/^$backup_id/d" /tmp/vz7_backup-del.$$
	return 0
}

delete_backup_by_days(){
	local older_than_days=$1
	if ! echo "$older_than_days" | grep -q -E '^?[0-9]+$'; then
		echo "Указано неверное количество дней $older_than_days"
		rm -f /tmp/vz7_backup-del.$$
		exit 255
	fi
	if [ "$older_than_days" = "0" ]; then
		echo "TODO удаление всех бекапов с опцией --ALL"
		rm -f /tmp/vz7_backup-del.$$
		exit 255
	fi
	local current_time="$(date +%s)"
	local backup_time
	while read -r backup_time tail; do
		if [ $((current_time-backup_time)) -gt $((60*60*24*older_than_days)) ]; then
			delete_backup_by_id "$backup_time"
		fi
	done <<<"$(sort -n /tmp/vz7_backup-del.$$)"
	return 0
}

delete_all(){
	local node_ip t trash
	# 1645750041 2022-02-25 03:47 192.168.122.12/vz/backup/vps371278/disk/.INFO/1645750041
	cut -d' ' -f4 < /tmp/vz7_backup-del.$$ | cut -d'/' -f1  > /tmp/vz7_backup-del-all-ip.$$
	if [ -f "/opt/fox_conf/node/${VM_NODE_BACKUP}/node.conf" ]; then
		(
			. "/opt/fox_conf/node/${VM_NODE_BACKUP}/node.conf"
			echo "$NODE_IP" >> /tmp/vz7_backup-del-all-ip.$$
		)
	fi
	trash="/vz/.trash/backup.${PLOOP_NAME}.$(date +%s)"
	while read -r node_ip t; do
		if [ "$(__exists_backup_on_node "$node_ip")" = TRUE ]; then
			__ssh "$node_ip" "mkdir -p $trash"
			echo "Move backup to trash: $node_ip mv -f /vz/backup/$PLOOP_NAME $trash"
			__ssh "$node_ip" "mv -f /vz/backup/$PLOOP_NAME $trash"
			if [ "${ARG_CLEAN_TRASH:-}" = TRUE ]; then
				__ssh "$node_ip" "rm -rf --one-file-system $trash"
			fi
		fi
	done <<< "$(sort -un /tmp/vz7_backup-del-all-ip.$$)"
	rm -f /tmp/vz7_backup-del-all-ip.$$
	return 0
}

# todo: полное удаление бекапа. Когда будем реализовывать, решить, что мб сначала в корзину
if [ -n "${ARG_OLDER_THAN_DAYS:-}" ]; then
	delete_backup_by_days "$ARG_OLDER_THAN_DAYS"
elif [ "${ARG_ALL:-}" = "TRUE" ]; then
	delete_all
else
	echo "Не указаны параметры для удаления --older-than-days=XX или --all"
	rm -f /tmp/vz7_backup-del.$$
	exit 255
fi

rm -f /tmp/vz7_backup-del.$$

exit 0
