#!/bin/bash

# Vaultwarden SQLite Database Migration Script
# Safely migrates Vaultwarden data from lenovo410 to new Docker Swarm infrastructure

set -euo pipefail

# Configuration
SOURCE_HOST="jonathan@192.168.50.181"
SOURCE_PATH="/home/jonathan/vaultwarden/data"
BACKUP_DIR="./backups/vaultwarden"
TARGET_PATH="/export/vaultwarden"
LOG_FILE="./logs/vaultwarden_migration.log"

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

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

log_success() {
    echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')] SUCCESS:${NC} $1" | tee -a "$LOG_FILE"
}

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

log_error() {
    echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" | tee -a "$LOG_FILE"
}

# Create necessary directories
mkdir -p "$BACKUP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"

log "Starting Vaultwarden SQLite database migration"

# Step 1: Verify source Vaultwarden is running and healthy
log "Step 1: Verifying source Vaultwarden container status"
if ! ssh "$SOURCE_HOST" "docker ps | grep -q vaultwarden"; then
    log_error "Vaultwarden container is not running on $SOURCE_HOST"
    exit 1
fi

# Get container ID
CONTAINER_ID=$(ssh "$SOURCE_HOST" "docker ps | grep vaultwarden | awk '{print \$1}'")
log "Found Vaultwarden container: $CONTAINER_ID"

# Step 2: Create comprehensive backup
log "Step 2: Creating comprehensive backup of current Vaultwarden data"
BACKUP_FILE="$BACKUP_DIR/vaultwarden_backup_$(date +%Y%m%d_%H%M%S).tar.gz"

# Stop Vaultwarden temporarily for consistent backup
log "Stopping Vaultwarden container for consistent backup"
ssh "$SOURCE_HOST" "docker stop $CONTAINER_ID"

# Wait a moment for graceful shutdown
sleep 5

# Create backup
log "Creating backup archive"
ssh "$SOURCE_HOST" "tar czf - -C $SOURCE_PATH ." > "$BACKUP_FILE"

# Verify backup size
BACKUP_SIZE=$(stat -c%s "$BACKUP_FILE")
log "Backup created: $BACKUP_FILE (${BACKUP_SIZE} bytes)"

if [ "$BACKUP_SIZE" -lt 1000000 ]; then
    log_warning "Backup seems small, verifying contents"
    tar tzf "$BACKUP_FILE" | head -10
fi

# Step 3: Restart source Vaultwarden
log "Step 3: Restarting source Vaultwarden container"
ssh "$SOURCE_HOST" "docker start $CONTAINER_ID"

# Wait for container to be healthy
log "Waiting for Vaultwarden to be healthy"
for i in {1..30}; do
    if ssh "$SOURCE_HOST" "docker ps | grep -q vaultwarden.*healthy"; then
        log_success "Vaultwarden container is healthy"
        break
    fi
    if [ $i -eq 30 ]; then
        log_error "Vaultwarden container failed to become healthy"
        exit 1
    fi
    sleep 2
done

# Step 4: Verify NFS export exists and is accessible
log "Step 4: Verifying NFS export accessibility"
if [ ! -d "$TARGET_PATH" ]; then
    log_error "Target NFS path $TARGET_PATH does not exist"
    log "Please ensure the NFS export is properly configured on OMV800"
    exit 1
fi

# Test write access
if ! touch "$TARGET_PATH/test_write_access" 2>/dev/null; then
    log_error "Cannot write to target NFS path $TARGET_PATH"
    exit 1
fi
rm -f "$TARGET_PATH/test_write_access"

# Step 5: Extract backup to target location
log "Step 5: Extracting backup to target location"
cd "$TARGET_PATH"
tar xzf "$BACKUP_FILE"

# Verify extraction
if [ ! -f "$TARGET_PATH/db.sqlite3" ]; then
    log_error "SQLite database not found in target location"
    exit 1
fi

log_success "Database extracted to target location"

# Step 6: Set proper permissions
log "Step 6: Setting proper permissions"
chmod 644 "$TARGET_PATH/db.sqlite3"
chmod 644 "$TARGET_PATH/rsa_key.pem"
chmod -R 755 "$TARGET_PATH/attachments"
chmod -R 755 "$TARGET_PATH/icon_cache"
chmod -R 755 "$TARGET_PATH/sends"
chmod -R 755 "$TARGET_PATH/tmp"

# Step 7: Verify database integrity
log "Step 7: Verifying database integrity"
if [ -f "$TARGET_PATH/db.sqlite3" ]; then
    # Check if database is readable
    if file "$TARGET_PATH/db.sqlite3" | grep -q "SQLite"; then
        log_success "SQLite database format verified"
    else
        log_error "Database file does not appear to be a valid SQLite database"
        exit 1
    fi
else
    log_error "Database file not found in target location"
    exit 1
fi

# Step 8: Create Docker secret for admin token if it doesn't exist
log "Step 8: Creating admin token secret"
if ! docker secret ls | grep -q vaultwarden_admin_token; then
    # Generate a secure admin token
    ADMIN_TOKEN=$(openssl rand -base64 32)
    echo "$ADMIN_TOKEN" | docker secret create vaultwarden_admin_token -
    log_success "Created vaultwarden_admin_token secret"
    log "Admin token generated. You can access the admin interface at:"
    log "https://vaultwarden.pressmess.duckdns.org/admin"
    log "Token: $ADMIN_TOKEN"
else
    log "Admin token secret already exists"
fi

# Step 9: Deploy new Vaultwarden stack
log "Step 9: Deploying new Vaultwarden stack"
if docker stack deploy -c stacks/apps/vaultwarden.yml vaultwarden; then
    log_success "Vaultwarden stack deployed successfully"
else
    log_error "Failed to deploy Vaultwarden stack"
    exit 1
fi

# Step 10: Wait for new service to be ready
log "Step 10: Waiting for new Vaultwarden service to be ready"
for i in {1..60}; do
    if docker service ls | grep -q vaultwarden.*1/1; then
        log_success "New Vaultwarden service is running"
        break
    fi
    if [ $i -eq 60 ]; then
        log_error "New Vaultwarden service failed to start"
        exit 1
    fi
    sleep 5
done

# Step 11: Verify new service is accessible
log "Step 11: Verifying new service accessibility"
sleep 10  # Give service time to fully initialize

if curl -s -f "https://vaultwarden.pressmess.duckdns.org" > /dev/null; then
    log_success "New Vaultwarden service is accessible"
else
    log_warning "New Vaultwarden service may not be accessible yet (this is normal during startup)"
fi

# Step 12: Validation period
log "Step 12: Starting validation period"
log "Vaultwarden migration completed successfully!"
log ""
log "IMPORTANT: Please test the new Vaultwarden service for the next 24 hours:"
log "1. Access https://vaultwarden.pressmess.duckdns.org"
log "2. Verify all your passwords and data are present"
log "3. Test login/logout functionality"
log "4. Test password creation and editing"
log "5. Test browser extensions if you use them"
log ""
log "If everything works correctly after 24 hours, you can stop the old service:"
log "ssh $SOURCE_HOST 'docker stop $CONTAINER_ID'"
log ""
log "Backup location: $BACKUP_FILE"
log "Migration log: $LOG_FILE"

log_success "Vaultwarden SQLite migration completed successfully!"
