#!/bin/bash
# Config Backup & Rollback — SysOps safety net
# Run before any config change. Auto-snapshots on every call.
# Created: 2026-02-06
#
# Usage:
#   ./config-backup.sh snapshot          — Save current config
#   ./config-backup.sh list              — List available backups
#   ./config-backup.sh rollback [file]   — Restore a backup (latest if no file given)
#   ./config-backup.sh diff [file]       — Show diff between current and backup

set -euo pipefail

CONFIG_PATH="/root/.clawdbot/clawdbot.json"
BACKUP_DIR="/root/.clawdbot/config-backups"
MAX_BACKUPS=20

mkdir -p "$BACKUP_DIR"

action="${1:-snapshot}"

case "$action" in
    snapshot)
        if [ ! -f "$CONFIG_PATH" ]; then
            echo "❌ No config found at $CONFIG_PATH"
            exit 1
        fi
        
        TIMESTAMP=$(date '+%Y%m%d-%H%M%S')
        BACKUP_FILE="${BACKUP_DIR}/config-${TIMESTAMP}.json"
        
        cp "$CONFIG_PATH" "$BACKUP_FILE"
        
        # Also snapshot auth and model configs (these broke us on Feb 6)
        for extra in auth-profiles.json models.json; do
            if [ -f "/root/.clawdbot/${extra}" ]; then
                cp "/root/.clawdbot/${extra}" "${BACKUP_DIR}/${extra%.json}-${TIMESTAMP}.json"
            fi
        done
        
        # Verify the backup is valid JSON
        if jq empty "$BACKUP_FILE" 2>/dev/null; then
            echo "✅ Config backed up: $BACKUP_FILE"
            echo "   Size: $(wc -c < "$BACKUP_FILE") bytes"
            echo "   Hash: $(md5sum "$BACKUP_FILE" | cut -d' ' -f1)"
        else
            echo "⚠️ Config backed up but may not be valid JSON"
        fi
        
        # Prune old backups (keep latest $MAX_BACKUPS)
        BACKUP_COUNT=$(ls -1 "$BACKUP_DIR"/config-*.json 2>/dev/null | wc -l)
        if [ "$BACKUP_COUNT" -gt "$MAX_BACKUPS" ]; then
            PRUNE_COUNT=$((BACKUP_COUNT - MAX_BACKUPS))
            ls -1t "$BACKUP_DIR"/config-*.json | tail -n "$PRUNE_COUNT" | xargs rm -f
            echo "   Pruned $PRUNE_COUNT old backups (keeping $MAX_BACKUPS)"
        fi
        ;;
        
    list)
        echo "📂 Config backups in $BACKUP_DIR:"
        echo ""
        if ls "$BACKUP_DIR"/config-*.json 1>/dev/null 2>&1; then
            ls -lht "$BACKUP_DIR"/config-*.json | awk '{print "  " $6, $7, $8, $9, "(" $5 ")"}'
        else
            echo "  (none)"
        fi
        ;;
        
    rollback)
        RESTORE_FILE="${2:-}"
        
        if [ -z "$RESTORE_FILE" ]; then
            # Use latest backup
            RESTORE_FILE=$(ls -1t "$BACKUP_DIR"/config-*.json 2>/dev/null | head -1)
            if [ -z "$RESTORE_FILE" ]; then
                echo "❌ No backups found to rollback to"
                exit 1
            fi
        fi
        
        if [ ! -f "$RESTORE_FILE" ]; then
            # Try as filename in backup dir
            if [ -f "${BACKUP_DIR}/${RESTORE_FILE}" ]; then
                RESTORE_FILE="${BACKUP_DIR}/${RESTORE_FILE}"
            else
                echo "❌ Backup file not found: $RESTORE_FILE"
                exit 1
            fi
        fi
        
        # Validate JSON before restoring
        if ! jq empty "$RESTORE_FILE" 2>/dev/null; then
            echo "❌ Backup is not valid JSON — aborting rollback"
            exit 1
        fi
        
        # Snapshot current before overwriting
        TIMESTAMP=$(date '+%Y%m%d-%H%M%S')
        cp "$CONFIG_PATH" "${BACKUP_DIR}/config-pre-rollback-${TIMESTAMP}.json" 2>/dev/null || true
        
        # Restore
        cp "$RESTORE_FILE" "$CONFIG_PATH"
        echo "✅ Config restored from: $RESTORE_FILE"
        echo "   Pre-rollback saved as: config-pre-rollback-${TIMESTAMP}.json"
        echo ""
        echo "⚠️  Run 'systemctl restart clawdbot-gateway' to apply"
        ;;
        
    diff)
        COMPARE_FILE="${2:-}"
        
        if [ -z "$COMPARE_FILE" ]; then
            COMPARE_FILE=$(ls -1t "$BACKUP_DIR"/config-*.json 2>/dev/null | head -1)
            if [ -z "$COMPARE_FILE" ]; then
                echo "❌ No backups to compare against"
                exit 1
            fi
        fi
        
        if [ ! -f "$COMPARE_FILE" ]; then
            if [ -f "${BACKUP_DIR}/${COMPARE_FILE}" ]; then
                COMPARE_FILE="${BACKUP_DIR}/${COMPARE_FILE}"
            fi
        fi
        
        echo "📊 Diff: current config vs $(basename "$COMPARE_FILE")"
        echo ""
        diff --color=always <(jq -S . "$COMPARE_FILE") <(jq -S . "$CONFIG_PATH") || true
        ;;
        
    *)
        echo "Usage: $0 {snapshot|list|rollback [file]|diff [file]}"
        exit 1
        ;;
esac
