#!/usr/bin/env bash

set -Eeuo pipefail
shopt -s nullglob

source "$DOTS/config/zsh/config/colors.zsh" && define_colors

LOCAL_BACKUP_PATH="$HOME/Drives/Backups/auto-backups/"
REMOTE_BACKUP_PATH="auto-backups"
RCLONE_CLOUD_NAME="GDrive"

DATE_FORMAT="+%F"

# sources can be any rsync accepted path
SOURCES=(
	"$HOME/Drives/Stuff/Pictures/"
	"$HOME/Drives/Stuff/Music/"
	"root@berry.net:/home/aleidk/services/"
)

MAX_BACKUPS=10

ensure_path_exist() {
	path="$1"
	shift

	if [[ ! -d "$path" ]]; then
		echo -e "Path ${RED}$path${RST} doesn't exist, ${GRN}creating...${RST}"
		mkdir -p "$path"
	fi
}

backup() {
	src="$1"
	shift
	dst="$LOCAL_BACKUP_PATH"

	name="$(basename "$src")"
	dst="${dst}${name}"
	date=$(date "$DATE_FORMAT")

	# Config
	SNAP="${dst}/${date}"
	LAST="${dst}/last"
	PARTIAL="${dst}/.partial_${date}"

	# Check partial backups (failed)

	if [[ -d "$SNAP" && ! -d "$PARTIAL" ]]; then
		echo -e "${MGN}${DIM}Backup for $date already crated, skiping...${RST}"
		return
	else
		echo -e "Backing up ${BLU}$dst${RST}"
	fi

	# shellcheck disable=2086
	rsync \
		--fake-super \
		--compress \
		--mkpath \
		--archive \
		--human-readable \
		--delete \
		--filter='dir-merge /.sync-exclude' \
		--exclude="**/.sync-exclude" \
		--partial \
		--partial-dir="$PARTIAL" \
		--info=none,progress2 \
		--link-dest="$LAST" \
		"$src" "$SNAP"

	# Update symlink to last backup
	rm -f "$LAST"
	ln -s "$SNAP" "$LAST"

	# clean failed backups
	for dir in $dst/.partial_*; do
		date="$(echo "$dir" | cut -d "_" -f 2)"
		rm -r "$dir" "${dst:?}/${date}"
	done
	echo -e ""
}

delete_old() {
	src="$1"
	shift
	dst="$LOCAL_BACKUP_PATH"

	name="$(basename "$src")"
	dst="${dst}${name}"

	bkp_count="$(fd -t d --exact-depth 1 . "$dst" | wc -l)"

	while [[ $bkp_count -gt $MAX_BACKUPS ]]; do
		oldest_dir="$(fd -t d --exact-depth 1 . "$dst" | sort | head -n 1)"

		echo -e "Max backups exceed for ${BLU}$name${RST}, deleting ${RED}$(basename "$oldest_dir")${RST}..."

		rm -rf "$oldest_dir"

		bkp_count="$(fd -t d --exact-depth 1 . "${dst}" | wc -l)"
	done

	echo ""
}

sync() {
	config="$(rclone config dump 2>/dev/null | jq ".$RCLONE_CLOUD_NAME  // empty")"

	if [[ -z "$config" ]]; then
		echo -e "${RED}${SHL}No Rclone configuration! skiping sync.${RST}${EHL}\n"
		return
	fi

	for dir in $LOCAL_BACKUP_PATH/*; do
		name="$(basename "$dir")"
		remote_path="${RCLONE_CLOUD_NAME}:${REMOTE_BACKUP_PATH}/${name}"
		newest="$(fd -t d --exact-depth 1 . "$dir" | sort -r | head -n 1)"
		today=$(date "$DATE_FORMAT")

		if [[ "$today" == "$(rclone cat "${remote_path}/.last-sync" 2>/dev/null)" ]]; then
			echo -e "${MGN}${DIM}Last sync ${BLU}for${RST} $name was today, skiping...${RST}"
			continue
		else
			echo -e "Syncthing latest backup for ${BLU}$name${RST} in ${RED}$remote_path${RST}"
		fi

		rclone sync \
			--copy-links \
			--progress \
			--stats-one-line \
			"$newest" "$remote_path"

		echo "$today" | rclone rcat "${remote_path}/.last-sync"
	done

	echo ""
}

ensure_path_exist "$LOCAL_BACKUP_PATH"

for path in "${SOURCES[@]}"; do
	backup "$path"
	delete_old "$path"
done

# Sync to MEGA
# sync

echo -e "${GRN}Backups done!${RST}"
