apiVersion: v1
kind: ConfigMap
metadata:
  name: backup-scripts
  namespace: default
  labels:
    app: aitbc-backup
    component: backup
data:
  backup_postgresql.sh: |
    #!/bin/bash
    # PostgreSQL Backup Script for AITBC
    # Usage: ./backup_postgresql.sh [namespace] [backup_name]

    set -euo pipefail

    # Configuration
    NAMESPACE=${1:-default}
    BACKUP_NAME=${2:-postgresql-backup-$(date +%Y%m%d_%H%M%S)}
    BACKUP_DIR="/tmp/postgresql-backups"
    RETENTION_DAYS=30

    # Colors for output
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    NC='\033[0m' # No Color

    # Logging function
    log() {
        echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
    }

    error() {
        echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" >&2
    }

    warn() {
        echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1"
    }

    # Check dependencies
    check_dependencies() {
        if ! command -v kubectl &> /dev/null; then
            error "kubectl is not installed or not in PATH"
            exit 1
        fi
        
        if ! command -v pg_dump &> /dev/null; then
            error "pg_dump is not installed or not in PATH"
            exit 1
        fi
    }

    # Create backup directory
    create_backup_dir() {
        mkdir -p "$BACKUP_DIR"
        log "Created backup directory: $BACKUP_DIR"
    }

    # Get PostgreSQL pod name
    get_postgresql_pod() {
        local pod=$(kubectl get pods -n "$NAMESPACE" -l app.kubernetes.io/name=postgresql -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
        if [[ -z "$pod" ]]; then
            pod=$(kubectl get pods -n "$NAMESPACE" -l app=postgresql -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
        fi
        
        if [[ -z "$pod" ]]; then
            error "Could not find PostgreSQL pod in namespace $NAMESPACE"
            exit 1
        fi
        
        echo "$pod"
    }

    # Wait for PostgreSQL to be ready
    wait_for_postgresql() {
        local pod=$1
        log "Waiting for PostgreSQL pod $pod to be ready..."
        
        kubectl wait --for=condition=ready pod "$pod" -n "$NAMESPACE" --timeout=300s
        
        # Check if PostgreSQL is accepting connections
        local retries=30
        while [[ $retries -gt 0 ]]; do
            if kubectl exec -n "$NAMESPACE" "$pod" -- pg_isready -U postgres >/dev/null 2>&1; then
                log "PostgreSQL is ready"
                return 0
            fi
            sleep 2
            ((retries--))
        done
        
        error "PostgreSQL did not become ready within timeout"
        exit 1
    }

    # Perform backup
    perform_backup() {
        local pod=$1
        local backup_file="$BACKUP_DIR/${BACKUP_NAME}.sql"
        
        log "Starting PostgreSQL backup to $backup_file"
        
        # Get database credentials from secret
        local db_user=$(kubectl get secret -n "$NAMESPACE" coordinator-postgresql -o jsonpath='{.data.username}' 2>/dev/null | base64 -d || echo "postgres")
        local db_password=$(kubectl get secret -n "$NAMESPACE" coordinator-postgresql -o jsonpath='{.data.password}' 2>/dev/null | base64 -d || echo "")
        local db_name=$(kubectl get secret -n "$NAMESPACE" coordinator-postgresql -o jsonpath='{.data.database}' 2>/dev/null | base64 -d || echo "aitbc")
        
        # Perform the backup
        PGPASSWORD="$db_password" kubectl exec -n "$NAMESPACE" "$pod" -- \
            pg_dump -U "$db_user" -h localhost -d "$db_name" \
            --verbose --clean --if-exists --create --format=custom \
            --file="/tmp/${BACKUP_NAME}.dump"
        
        # Copy backup from pod
        kubectl cp "$NAMESPACE/$pod:/tmp/${BACKUP_NAME}.dump" "$backup_file"
        
        # Clean up remote backup file
        kubectl exec -n "$NAMESPACE" "$pod" -- rm -f "/tmp/${BACKUP_NAME}.dump"
        
        # Compress backup
        gzip "$backup_file"
        backup_file="${backup_file}.gz"
        
        log "Backup completed: $backup_file"
        
        # Verify backup
        if [[ -f "$backup_file" ]] && [[ -s "$backup_file" ]]; then
            local size=$(du -h "$backup_file" | cut -f1)
            log "Backup size: $size"
        else
            error "Backup file is empty or missing"
            exit 1
        fi
    }

    # Clean old backups
    cleanup_old_backups() {
        log "Cleaning up backups older than $RETENTION_DAYS days"
        find "$BACKUP_DIR" -name "*.sql.gz" -type f -mtime +$RETENTION_DAYS -delete
        log "Cleanup completed"
    }

    # Upload to cloud storage (optional)
    upload_to_cloud() {
        local backup_file="$1"
        
        # Check if AWS CLI is configured
        if command -v aws &> /dev/null && aws sts get-caller-identity &>/dev/null; then
            log "Uploading backup to S3"
            local s3_bucket="aitbc-backups-${NAMESPACE}"
            local s3_key="postgresql/$(basename "$backup_file")"
            
            aws s3 cp "$backup_file" "s3://$s3_bucket/$s3_key" --storage-class GLACIER_IR
            log "Backup uploaded to s3://$s3_bucket/$s3_key"
        else
            warn "AWS CLI not configured, skipping cloud upload"
        fi
    }

    # Main execution
    main() {
        log "Starting PostgreSQL backup process"
        
        check_dependencies
        create_backup_dir
        
        local pod=$(get_postgresql_pod)
        wait_for_postgresql "$pod"
        
        perform_backup "$pod"
        cleanup_old_backups
        
        local backup_file="$BACKUP_DIR/${BACKUP_NAME}.sql.gz"
        upload_to_cloud "$backup_file"
        
        log "PostgreSQL backup process completed successfully"
    }

    # Run main function
    main "$@"

  backup_redis.sh: |
    #!/bin/bash
    # Redis Backup Script for AITBC
    # Usage: ./backup_redis.sh [namespace] [backup_name]

    set -euo pipefail

    # Configuration
    NAMESPACE=${1:-default}
    BACKUP_NAME=${2:-redis-backup-$(date +%Y%m%d_%H%M%S)}
    BACKUP_DIR="/tmp/redis-backups"
    RETENTION_DAYS=30

    # Colors for output
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    NC='\033[0m' # No Color

    # Logging function
    log() {
        echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
    }

    error() {
        echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" >&2
    }

    warn() {
        echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1"
    }

    # Check dependencies
    check_dependencies() {
        if ! command -v kubectl &> /dev/null; then
            error "kubectl is not installed or not in PATH"
            exit 1
        fi
    }

    # Create backup directory
    create_backup_dir() {
        mkdir -p "$BACKUP_DIR"
        log "Created backup directory: $BACKUP_DIR"
    }

    # Get Redis pod name
    get_redis_pod() {
        local pod=$(kubectl get pods -n "$NAMESPACE" -l app.kubernetes.io/name=redis -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
        if [[ -z "$pod" ]]; then
            pod=$(kubectl get pods -n "$NAMESPACE" -l app=redis -o jsonpath='{.items[0].metadata.name}' 2>/dev/null || echo "")
        fi
        
        if [[ -z "$pod" ]]; then
            error "Could not find Redis pod in namespace $NAMESPACE"
            exit 1
        fi
        
        echo "$pod"
    }

    # Wait for Redis to be ready
    wait_for_redis() {
        local pod=$1
        log "Waiting for Redis pod $pod to be ready..."
        
        kubectl wait --for=condition=ready pod "$pod" -n "$NAMESPACE" --timeout=300s
        
        # Check if Redis is accepting connections
        local retries=30
        while [[ $retries -gt 0 ]]; do
            if kubectl exec -n "$NAMESPACE" "$pod" -- redis-cli ping 2>/dev/null | grep -q PONG; then
                log "Redis is ready"
                return 0
            fi
            sleep 2
            ((retries--))
        done
        
        error "Redis did not become ready within timeout"
        exit 1
    }

    # Perform backup
    perform_backup() {
        local pod=$1
        local backup_file="$BACKUP_DIR/${BACKUP_NAME}.rdb"
        
        log "Starting Redis backup to $backup_file"
        
        # Create Redis backup
        kubectl exec -n "$NAMESPACE" "$pod" -- redis-cli BGSAVE
        
        # Wait for background save to complete
        log "Waiting for background save to complete..."
        local retries=60
        while [[ $retries -gt 0 ]]; do
            local lastsave=$(kubectl exec -n "$NAMESPACE" "$pod" -- redis-cli LASTSAVE)
            local lastbgsave=$(kubectl exec -n "$NAMESPACE" "$pod" -- redis-cli LASTSAVE)
            
            if [[ "$lastsave" -gt "$lastbgsave" ]]; then
                log "Background save completed"
                break
            fi
            sleep 2
            ((retries--))
        done
        
        if [[ $retries -eq 0 ]]; then
            error "Background save did not complete within timeout"
            exit 1
        fi
        
        # Copy RDB file from pod
        kubectl cp "$NAMESPACE/$pod:/data/dump.rdb" "$backup_file"
        
        # Also create an append-only file backup if enabled
        local aof_enabled=$(kubectl exec -n "$NAMESPACE" "$pod" -- redis-cli CONFIG GET appendonly | tail -1)
        if [[ "$aof_enabled" == "yes" ]]; then
            local aof_backup="$BACKUP_DIR/${BACKUP_NAME}.aof"
            kubectl cp "$NAMESPACE/$pod:/data/appendonly.aof" "$aof_backup"
            log "AOF backup created: $aof_backup"
        fi
        
        log "Backup completed: $backup_file"
        
        # Verify backup
        if [[ -f "$backup_file" ]] && [[ -s "$backup_file" ]]; then
            local size=$(du -h "$backup_file" | cut -f1)
            log "Backup size: $size"
        else
            error "Backup file is empty or missing"
            exit 1
        fi
    }

    # Clean old backups
    cleanup_old_backups() {
        log "Cleaning up backups older than $RETENTION_DAYS days"
        find "$BACKUP_DIR" -name "*.rdb" -type f -mtime +$RETENTION_DAYS -delete
        find "$BACKUP_DIR" -name "*.aof" -type f -mtime +$RETENTION_DAYS -delete
        log "Cleanup completed"
    }

    # Upload to cloud storage (optional)
    upload_to_cloud() {
        local backup_file="$1"
        
        # Check if AWS CLI is configured
        if command -v aws &> /dev/null && aws sts get-caller-identity &>/dev/null; then
            log "Uploading backup to S3"
            local s3_bucket="aitbc-backups-${NAMESPACE}"
            local s3_key="redis/$(basename "$backup_file")"
            
            aws s3 cp "$backup_file" "s3://$s3_bucket/$s3_key" --storage-class GLACIER_IR
            log "Backup uploaded to s3://$s3_bucket/$s3_key"
            
            # Upload AOF file if exists
            local aof_file="${backup_file%.rdb}.aof"
            if [[ -f "$aof_file" ]]; then
                local aof_key="redis/$(basename "$aof_file")"
                aws s3 cp "$aof_file" "s3://$s3_bucket/$aof_key" --storage-class GLACIER_IR
                log "AOF backup uploaded to s3://$s3_bucket/$aof_key"
            fi
        else
            warn "AWS CLI not configured, skipping cloud upload"
        fi
    }

    # Main execution
    main() {
        log "Starting Redis backup process"
        
        check_dependencies
        create_backup_dir
        
        local pod=$(get_redis_pod)
        wait_for_redis "$pod"
        
        perform_backup "$pod"
        cleanup_old_backups
        
        local backup_file="$BACKUP_DIR/${BACKUP_NAME}.rdb"
        upload_to_cloud "$backup_file"
        
        log "Redis backup process completed successfully"
    }

    # Run main function
    main "$@"

  backup_ledger.sh: |
    #!/bin/bash
    # Ledger Storage Backup Script for AITBC
    # Usage: ./backup_ledger.sh [namespace] [backup_name]

    set -euo pipefail

    # Configuration
    NAMESPACE=${1:-default}
    BACKUP_NAME=${2:-ledger-backup-$(date +%Y%m%d_%H%M%S)}
    BACKUP_DIR="/tmp/ledger-backups"
    RETENTION_DAYS=30

    # Colors for output
    RED='\033[0;31m'
    GREEN='\033[0;32m'
    YELLOW='\033[1;33m'
    NC='\033[0m' # No Color

    # Logging function
    log() {
        echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
    }

    error() {
        echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" >&2
    }

    warn() {
        echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1"
    }

    # Check dependencies
    check_dependencies() {
        if ! command -v kubectl &> /dev/null; then
            error "kubectl is not installed or not in PATH"
            exit 1
        fi
    }

    # Create backup directory
    create_backup_dir() {
        mkdir -p "$BACKUP_DIR"
        log "Created backup directory: $BACKUP_DIR"
    }

    # Get blockchain node pods
    get_blockchain_pods() {
        local pods=$(kubectl get pods -n "$NAMESPACE" -l app.kubernetes.io/name=blockchain-node -o jsonpath='{.items[*].metadata.name}' 2>/dev/null || echo "")
        if [[ -z "$pods" ]]; then
            pods=$(kubectl get pods -n "$NAMESPACE" -l app=blockchain-node -o jsonpath='{.items[*].metadata.name}' 2>/dev/null || echo "")
        fi
        
        if [[ -z "$pods" ]]; then
            error "Could not find blockchain node pods in namespace $NAMESPACE"
            exit 1
        fi
        
        echo $pods
    }

    # Wait for blockchain node to be ready
    wait_for_blockchain_node() {
        local pod=$1
        log "Waiting for blockchain node pod $pod to be ready..."
        
        kubectl wait --for=condition=ready pod "$pod" -n "$NAMESPACE" --timeout=300s
        
        # Check if node is responding
        local retries=30
        while [[ $retries -gt 0 ]]; do
            if kubectl exec -n "$NAMESPACE" "$pod" -- curl -s http://localhost:8080/v1/health >/dev/null 2>&1; then
                log "Blockchain node is ready"
                return 0
            fi
            sleep 2
            ((retries--))
        done
        
        error "Blockchain node did not become ready within timeout"
        exit 1
    }

    # Backup ledger data
    backup_ledger_data() {
        local pod=$1
        local ledger_backup_dir="$BACKUP_DIR/${BACKUP_NAME}"
        mkdir -p "$ledger_backup_dir"
        
        log "Starting ledger backup from pod $pod"
        
        # Get the latest block height before backup
        local latest_block=$(kubectl exec -n "$NAMESPACE" "$pod" -- curl -s http://localhost:8080/v1/blocks/head | jq -r '.height // 0')
        log "Latest block height: $latest_block"
        
        # Backup blockchain data directory
        local blockchain_data_dir="/app/data/chain"
        if kubectl exec -n "$NAMESPACE" "$pod" -- test -d "$blockchain_data_dir"; then
            log "Backing up blockchain data directory..."
            kubectl exec -n "$NAMESPACE" "$pod" -- tar -czf "/tmp/${BACKUP_NAME}-chain.tar.gz" -C "$blockchain_data_dir" .
            kubectl cp "$NAMESPACE/$pod:/tmp/${BACKUP_NAME}-chain.tar.gz" "$ledger_backup_dir/chain.tar.gz"
            kubectl exec -n "$NAMESPACE" "$pod" -- rm -f "/tmp/${BACKUP_NAME}-chain.tar.gz"
        fi
        
        # Backup wallet data
        local wallet_data_dir="/app/data/wallets"
        if kubectl exec -n "$NAMESPACE" "$pod" -- test -d "$wallet_data_dir"; then
            log "Backing up wallet data directory..."
            kubectl exec -n "$NAMESPACE" "$pod" -- tar -czf "/tmp/${BACKUP_NAME}-wallets.tar.gz" -C "$wallet_data_dir" .
            kubectl cp "$NAMESPACE/$pod:/tmp/${BACKUP_NAME}-wallets.tar.gz" "$ledger_backup_dir/wallets.tar.gz"
            kubectl exec -n "$NAMESPACE" "$pod" -- rm -f "/tmp/${BACKUP_NAME}-wallets.tar.gz"
        fi
        
        # Backup receipts
        local receipts_data_dir="/app/data/receipts"
        if kubectl exec -n "$NAMESPACE" "$pod" -- test -d "$receipts_data_dir"; then
            log "Backing up receipts directory..."
            kubectl exec -n "$NAMESPACE" "$pod" -- tar -czf "/tmp/${BACKUP_NAME}-receipts.tar.gz" -C "$receipts_data_dir" .
            kubectl cp "$NAMESPACE/$pod:/tmp/${BACKUP_NAME}-receipts.tar.gz" "$ledger_backup_dir/receipts.tar.gz"
            kubectl exec -n "$NAMESPACE" "$pod" -- rm -f "/tmp/${BACKUP_NAME}-receipts.tar.gz"
        fi
        
        # Create metadata file
        cat > "$ledger_backup_dir/metadata.json" << EOF
    {
      "backup_name": "$BACKUP_NAME",
      "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
      "namespace": "$NAMESPACE",
      "source_pod": "$pod",
      "latest_block_height": $latest_block,
      "backup_type": "full"
    }
    EOF
        
        log "Ledger backup completed: $ledger_backup_dir"
        
        # Verify backup
        local total_size=$(du -sh "$ledger_backup_dir" | cut -f1)
        log "Total backup size: $total_size"
    }

    # Clean old backups
    cleanup_old_backups() {
        log "Cleaning up backups older than $RETENTION_DAYS days"
        find "$BACKUP_DIR" -maxdepth 1 -type d -name "ledger-backup-*" -mtime +$RETENTION_DAYS -exec rm -rf {} \;
        find "$BACKUP_DIR" -name "*-incremental.json" -type f -mtime +$RETENTION_DAYS -delete
        log "Cleanup completed"
    }

    # Upload to cloud storage (optional)
    upload_to_cloud() {
        local backup_dir="$1"
        
        # Check if AWS CLI is configured
        if command -v aws &> /dev/null && aws sts get-caller-identity &>/dev/null; then
            log "Uploading backup to S3"
            local s3_bucket="aitbc-backups-${NAMESPACE}"
            
            # Upload entire backup directory
            aws s3 cp "$backup_dir" "s3://$s3_bucket/ledger/$(basename "$backup_dir")/" --recursive --storage-class GLACIER_IR
            
            log "Backup uploaded to s3://$s3_bucket/ledger/$(basename "$backup_dir")/"
        else
            warn "AWS CLI not configured, skipping cloud upload"
        fi
    }

    # Main execution
    main() {
        log "Starting ledger backup process"
        
        check_dependencies
        create_backup_dir
        
        local pods=($(get_blockchain_pods))
        
        # Use the first ready pod for backup
        for pod in "${pods[@]}"; do
            if kubectl wait --for=condition=ready pod "$pod" -n "$NAMESPACE" --timeout=10s >/dev/null 2>&1; then
                wait_for_blockchain_node "$pod"
                backup_ledger_data "$pod"
                
                local backup_dir="$BACKUP_DIR/${BACKUP_NAME}"
                upload_to_cloud "$backup_dir"
                
                break
            fi
        done
        
        cleanup_old_backups
        
        log "Ledger backup process completed successfully"
    }

    # Run main function
    main "$@"
