#!/usr/bin/env bash
set -Eeuo pipefail

BACKUP_ROOT=/home/admin/backups/sub2api
DATE_TAG=${DATE_TAG:-$(date +%Y%m%d)}
BACKUP_DIR="$BACKUP_ROOT/backup-date-$DATE_TAG"
LOG_FILE="$BACKUP_ROOT/backup.log"
CRON_LOG="$BACKUP_ROOT/cron.log"
KEY_FILE=/home/admin/.ssh/id_backup
TRASH_DIR=/home/admin/.trash
RETAIN_DAYS=2

TARGETS=(
  "ny159|22|root@159.203.172.233|/srv/backups/sub2api"
  "sg168|22|root@168.144.101.105|/srv/backups/sub2api"
  "sg74|22|root@74.48.114.71|/srv/backups/sub2api"
)

log() {
  printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*" | tee -a "$LOG_FILE"
}

fail() {
  log "FATAL: $*"
  exit 1
}

cleanup_remote_old_backups() {
  local name="$1"
  local port="$2"
  local userhost="$3"
  local dest_root="$4"

  ssh -i "$KEY_FILE" -o BatchMode=yes -o StrictHostKeyChecking=no -p "$port" "$userhost" \
    "DEST_ROOT='$dest_root' RETAIN_DAYS='$RETAIN_DAYS' bash -s" <<'REMOTE'
set -Eeuo pipefail
trash_dir="$DEST_ROOT/.trash"
mkdir -p "$trash_dir"
mapfile -t dirs < <(find "$DEST_ROOT" -maxdepth 1 -mindepth 1 -type d -name 'backup-date-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]' | sort)
if [ "${#dirs[@]}" -le "$RETAIN_DAYS" ]; then
  exit 0
fi
for ((idx=0; idx<${#dirs[@]}-RETAIN_DAYS; idx++)); do
  dir="${dirs[$idx]}"
  mv "$dir" "$trash_dir/$(basename "$dir")_$(date +%Y%m%d_%H%M%S)"
done
REMOTE

  log "$name 旧备份保留策略已执行：仅保留最近 $RETAIN_DAYS 天"
}

sync_with_logs() {
  local name="$1"
  shift
  set +e
  "$@" 2>&1 | sed "s/^/[${name}] /" | tee -a "$LOG_FILE"
  local cmd_rc=${PIPESTATUS[0]}
  set -e
  return "$cmd_rc"
}

mkdir -p "$TRASH_DIR"
touch "$LOG_FILE" "$CRON_LOG"

[ -d "$BACKUP_DIR" ] || fail "本地备份目录不存在，无法同步: $BACKUP_DIR"
[ -f "$KEY_FILE" ] || fail "缺少备份私钥: $KEY_FILE"
command -v rsync >/dev/null 2>&1 || fail 'rsync 不存在'
command -v ssh >/dev/null 2>&1 || fail 'ssh 不存在'

log '===== 开始远端同步（独立 service） ====='
log "backup_dir=$BACKUP_DIR"

FAILED_TARGETS=()
for item in "${TARGETS[@]}"; do
  IFS='|' read -r NAME PORT USERHOST DEST_ROOT <<< "$item"
  DEST_DIR="$DEST_ROOT/backup-date-$DATE_TAG"
  log "开始同步到 $NAME: $USERHOST:$DEST_DIR"
  if ssh -i "$KEY_FILE" -o BatchMode=yes -o StrictHostKeyChecking=no -p "$PORT" "$USERHOST" "mkdir -p '$DEST_DIR' '$DEST_ROOT'" \
    && sync_with_logs "$NAME" rsync -az --partial --append-verify --delete --info=progress2,stats2 -e "ssh -i $KEY_FILE -o BatchMode=yes -o StrictHostKeyChecking=no -p $PORT" "$BACKUP_DIR/" "$USERHOST:$DEST_DIR/" \
    && sync_with_logs "$NAME-log" rsync -az --partial --append-verify -e "ssh -i $KEY_FILE -o BatchMode=yes -o StrictHostKeyChecking=no -p $PORT" "$LOG_FILE" "$CRON_LOG" "$USERHOST:$DEST_ROOT/"; then
    log "$NAME 同步成功"
    cleanup_remote_old_backups "$NAME" "$PORT" "$USERHOST" "$DEST_ROOT"
  else
    log "$NAME 同步失败"
    FAILED_TARGETS+=("$NAME")
  fi
done

if [ ${#FAILED_TARGETS[@]} -gt 0 ]; then
  fail "以下目标同步失败: ${FAILED_TARGETS[*]}"
fi

log '===== 远端同步完成 ====='
