#!/bin/bash

# WHP Password Encryption Update Script
# This script enables password encryption for existing installations

set -eE  # Exit on any error, but allow us to handle them
trap 'echo "Error on line $LINENO"' ERR

KEY_FILE="/etc/whp/encryption.key"
BACKUP_DIR="/root/whp-backups"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)

echo "🔐 WHP Password Encryption Setup"
echo "================================"

# Check if running as root
if [ "$EUID" -ne 0 ]; then
    echo "❌ This script must be run as root"
    exit 1
fi

# Create backup directory
mkdir -p "$BACKUP_DIR"

# Step 1: Backup database
echo "📦 Creating database backup..."
BACKUP_FILE="$BACKUP_DIR/whp_database_backup_$TIMESTAMP.sql"
mysqldump whp > "$BACKUP_FILE"
if [ $? -eq 0 ]; then
    echo "✅ Database backed up to: $BACKUP_FILE"
else
    echo "❌ Database backup failed!"
    exit 1
fi

# Step 2: Generate encryption key if it doesn't exist
if [ ! -f "$KEY_FILE" ]; then
    echo "🔑 Generating encryption key..."
    
    # Create directory if it doesn't exist
    mkdir -p /etc/whp
    
    # Generate 256-bit key
    NEW_KEY=$(openssl rand -base64 32)
    echo "$NEW_KEY" > "$KEY_FILE"
    chmod 600 "$KEY_FILE"
    chown root:root "$KEY_FILE"
    
    echo "✅ Encryption key generated: $KEY_FILE"
    echo "⚠️  IMPORTANT: Key content below - save this securely!"
    echo "📋 Key: $NEW_KEY"
    echo ""
else
    echo "✅ Encryption key already exists: $KEY_FILE"
fi

# Step 3: Migrate existing passwords
echo "🔄 Migrating existing passwords to encryption..."

# Get list of users with passwords
USERS=$(mysql -N -e "SELECT username FROM whp.user_passwords WHERE mysql_password IS NOT NULL AND LENGTH(mysql_password) > 0")

if [ -z "$USERS" ]; then
    echo "ℹ️  No users found with stored passwords"
else
    MIGRATED=0
    FAILED=0
    # Ensure arithmetic operations work
    set +e
    
    for USERNAME in $USERS; do
        echo -n "   Processing $USERNAME... "
        
        # Get current password and check if it's already encrypted
        CURRENT_PASSWORD=$(mysql -N -e "SELECT mysql_password FROM whp.user_passwords WHERE username = '$USERNAME'")
        
        if [ -n "$CURRENT_PASSWORD" ]; then
            # Check if password is already encrypted (encrypted passwords are much longer)
            if [ ${#CURRENT_PASSWORD} -gt 50 ]; then
                echo "✅ Already encrypted, skipping"
                continue
            fi
            # Try to decode base64, fall back to treating as plaintext
            PLAINTEXT=""
            if echo "$CURRENT_PASSWORD" | base64 -d >/dev/null 2>&1; then
                # Valid base64, decode it
                PLAINTEXT=$(echo "$CURRENT_PASSWORD" | base64 -d 2>/dev/null)
            else
                # Not valid base64, treat as plaintext
                PLAINTEXT="$CURRENT_PASSWORD"
            fi
            
            # Skip if plaintext is empty
            if [ -z "$PLAINTEXT" ]; then
                echo "⚠️  Empty password, skipping"
                continue
            fi
            
            # Use PHP to encrypt with new system (escape the plaintext for PHP)
            ESCAPED_PLAINTEXT=$(printf '%s\n' "$PLAINTEXT" | sed "s/'/\\\\'/g")
            ENCRYPTED=$(php -r "
                require_once('/docker/whp/web/libs/usermgmt.php');
                \$usermgmt = new usermgmt();
                \$reflection = new ReflectionClass(\$usermgmt);
                \$method = \$reflection->getMethod('encryptPassword');
                \$method->setAccessible(true);
                try {
                    echo \$method->invoke(\$usermgmt, '$ESCAPED_PLAINTEXT');
                } catch (Exception \$e) {
                    echo 'ERROR: ' . \$e->getMessage();
                    exit(1);
                }
            " 2>&1 || true)
            
            if [[ $ENCRYPTED == ERROR:* ]]; then
                echo "❌ Failed - ${ENCRYPTED#ERROR: }"
                FAILED=$((FAILED + 1))
            else
                # Update database with encrypted password
                mysql -e "UPDATE whp.user_passwords SET mysql_password = '$ENCRYPTED' WHERE username = '$USERNAME'"
                if [ $? -eq 0 ]; then
                    echo "✅ Migrated"
                    MIGRATED=$((MIGRATED + 1))
                else
                    echo "❌ Database update failed"
                    FAILED=$((FAILED + 1))
                fi
            fi
        else
            echo "⚠️  No password found"
        fi
    done
    
    # Re-enable strict error checking
    set -e
    
    echo ""
    echo "📊 Migration Summary:"
    echo "   ✅ Migrated: $MIGRATED users"
    echo "   ❌ Failed: $FAILED users"
    echo "   ℹ️  Total processed: $(echo "$USERS" | wc -w) users"
    
    if [ $FAILED -gt 0 ]; then
        echo "⚠️  Some migrations failed. Check logs and use reset-user-password.sh if needed."
    fi
fi

# Step 4: Migrate PostgreSQL passwords if any exist
echo "🔄 Checking PostgreSQL passwords..."
PG_USERS=$(mysql -N -e "SELECT username FROM whp.user_passwords WHERE postgresql_password IS NOT NULL AND LENGTH(postgresql_password) > 0")

if [ -n "$PG_USERS" ]; then
    echo "🔄 Migrating PostgreSQL passwords..."
    PG_MIGRATED=0
    PG_FAILED=0
    # Ensure arithmetic operations work
    set +e
    
    for USERNAME in $PG_USERS; do
        echo -n "   Processing PostgreSQL password for $USERNAME... "
        
        CURRENT_PG_PASSWORD=$(mysql -N -e "SELECT postgresql_password FROM whp.user_passwords WHERE username = '$USERNAME'")
        
        if [ -n "$CURRENT_PG_PASSWORD" ]; then
            # Check if password is already encrypted (encrypted passwords are much longer)
            if [ ${#CURRENT_PG_PASSWORD} -gt 50 ]; then
                echo "✅ Already encrypted, skipping"
                continue
            fi
            # Try to decode base64, fall back to treating as plaintext
            PG_PLAINTEXT=""
            if echo "$CURRENT_PG_PASSWORD" | base64 -d >/dev/null 2>&1; then
                # Valid base64, decode it
                PG_PLAINTEXT=$(echo "$CURRENT_PG_PASSWORD" | base64 -d 2>/dev/null)
            else
                # Not valid base64, treat as plaintext
                PG_PLAINTEXT="$CURRENT_PG_PASSWORD"
            fi
            
            # Skip if plaintext is empty
            if [ -z "$PG_PLAINTEXT" ]; then
                echo "⚠️  Empty password, skipping"
                continue
            fi
            
            # Use PHP to encrypt with new system (escape the plaintext for PHP)
            ESCAPED_PG_PLAINTEXT=$(printf '%s\n' "$PG_PLAINTEXT" | sed "s/'/\\\\'/g")
            PG_ENCRYPTED=$(php -r "
                require_once('/docker/whp/web/libs/usermgmt.php');
                \$usermgmt = new usermgmt();
                \$reflection = new ReflectionClass(\$usermgmt);
                \$method = \$reflection->getMethod('encryptPassword');
                \$method->setAccessible(true);
                try {
                    echo \$method->invoke(\$usermgmt, '$ESCAPED_PG_PLAINTEXT');
                } catch (Exception \$e) {
                    echo 'ERROR: ' . \$e->getMessage();
                    exit(1);
                }
            " 2>&1 || true)
            
            if [[ $PG_ENCRYPTED == ERROR:* ]]; then
                echo "❌ Failed - ${PG_ENCRYPTED#ERROR: }"
                PG_FAILED=$((PG_FAILED + 1))
            else
                # Update database with encrypted password
                mysql -e "UPDATE whp.user_passwords SET postgresql_password = '$PG_ENCRYPTED' WHERE username = '$USERNAME'"
                if [ $? -eq 0 ]; then
                    echo "✅ Migrated"
                    PG_MIGRATED=$((PG_MIGRATED + 1))
                else
                    echo "❌ Database update failed"
                    PG_FAILED=$((PG_FAILED + 1))
                fi
            fi
        fi
    done
    
    # Re-enable strict error checking
    set -e
    
    echo "📊 PostgreSQL Migration Summary:"
    echo "   ✅ Migrated: $PG_MIGRATED users"
    echo "   ❌ Failed: $PG_FAILED users"
fi

echo ""
echo "🎉 Password encryption setup complete!"
echo ""
echo "📋 Important Notes:"
echo "   🔑 Encryption key: $KEY_FILE"
echo "   📦 Database backup: $BACKUP_FILE"
echo "   📁 Backup directory: $BACKUP_DIR"
echo ""
echo "⚠️  CRITICAL: Download and securely store the encryption key!"
if [ ! -f "$KEY_FILE.backup" ]; then
    echo "⚠️  Consider copying the key file to a secure location:"
    echo "     cp $KEY_FILE /path/to/secure/location/"
fi
echo ""
echo "✅ New passwords will now be automatically encrypted"
echo "✅ Existing passwords have been migrated to encryption"