#!/bin/bash
# Sync OpenClaw VM config to ~/lab/swarm and back up to MinIO
#
# Local:  rsync ~/.openclaw/ → ~/lab/swarm/openclaw/  (live mirror, no archive)
# MinIO:  timestamped archive → s3://zap/backups/      (point-in-time recovery)

set -euo pipefail

INSTANCE="${1:-zap}"
REGISTRY="${HOME}/.claude/state/openclaw-instances.json"
SYNC_DIR="${HOME}/lab/swarm/openclaw"
MINIO_BUCKET="zap"
MINIO_PREFIX="backups"
KEEP=7

# Resolve instance from registry
GUEST_HOST=$(python3 -c "
import json, sys
data = json.load(open('${REGISTRY}'))
inst = next((i for i in data['instances'] if i['name'] == '${INSTANCE}'), None)
if not inst:
    print('ERROR: unknown instance', file=sys.stderr); sys.exit(1)
if not inst.get('host'):
    print('ERROR: instance has no host', file=sys.stderr); sys.exit(1)
print(inst['host'])
")
GUEST_USER=$(python3 -c "
import json
data = json.load(open('${REGISTRY}'))
inst = next(i for i in data['instances'] if i['name'] == '${INSTANCE}')
print(inst['user'])
")

TIMESTAMP=$(date +%Y%m%d_%H%M%S)

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Syncing ${INSTANCE} (${GUEST_HOST})..."

# Check VM is reachable
if ! ssh -o ConnectTimeout=5 -o BatchMode=yes "root@${GUEST_HOST}" "echo ok" &>/dev/null; then
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: Cannot reach ${GUEST_HOST}" >&2
    exit 1
fi

mkdir -p "${SYNC_DIR}"

# Rsync ~/.openclaw/ → ~/lab/swarm/openclaw/
# Excludes large/ephemeral data not needed for redeployment
rsync -az --delete \
    --exclude='workspace/' \
    --exclude='extensions-quarantine/' \
    --exclude='logs/' \
    --exclude='*.bak' \
    --exclude='*.bak.*' \
    --exclude='*.bak-*' \
    --exclude='*.backup-*' \
    --exclude='*.pre-*' \
    --exclude='*.failed' \
    -e "ssh -o BatchMode=yes" \
    "root@${GUEST_HOST}:/home/${GUEST_USER}/.openclaw/" \
    "${SYNC_DIR}/"

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Synced to ${SYNC_DIR}"

# Create archive from synced files and upload to MinIO
ARCHIVE=$(mktemp --suffix=".tar.gz")
trap 'rm -f "${ARCHIVE}"' EXIT

tar czf "${ARCHIVE}" -C "${HOME}/lab/swarm" openclaw
MINIO_KEY="${MINIO_PREFIX}/${INSTANCE}-${TIMESTAMP}.tar.gz"
aws s3 cp "${ARCHIVE}" "s3://${MINIO_BUCKET}/${MINIO_KEY}" --quiet

SIZE=$(du -sh "${ARCHIVE}" | cut -f1)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] MinIO: s3://${MINIO_BUCKET}/${MINIO_KEY} (${SIZE})"

# Prune MinIO backups, keep last N
mapfile -t OLD_KEYS < <(aws s3 ls "s3://${MINIO_BUCKET}/${MINIO_PREFIX}/${INSTANCE}-" \
    | awk '{print $4}' | sort | head -n -${KEEP})
for key in "${OLD_KEYS[@]:-}"; do
    [[ -z "${key}" ]] && continue
    aws s3 rm "s3://${MINIO_BUCKET}/${MINIO_PREFIX}/${key}" --quiet
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] Pruned MinIO: ${key}"
done

echo "[$(date '+%Y-%m-%d %H:%M:%S')] Done."
