#!/bin/bash

# Database Migration Script
# Handles database schema migrations and data updates

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
DB_PATH="${PROJECT_ROOT}/data/metadata.db"

echo "🔄 Database Migration Script"
echo "==========================="

cd "$PROJECT_ROOT"

# Check if database exists
if [ ! -f "$DB_PATH" ]; then
    echo "❌ Database not found: $DB_PATH"
    echo "Please ensure the gateway has been initialized first"
    exit 1
fi

# Create backup before migration
echo "💾 Creating pre-migration backup..."
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="./backups/pre_migration_${TIMESTAMP}.sql"
mkdir -p backups

sqlite3 "$DB_PATH" .dump > "$BACKUP_FILE"
echo "✅ Backup created: $BACKUP_FILE"

# Check current schema version
echo "📊 Checking current schema..."
CURRENT_TABLES=$(sqlite3 "$DB_PATH" ".tables")
echo "Current tables: $CURRENT_TABLES"

# Migration functions
run_migration() {
    local version="$1"
    local description="$2"
    local sql="$3"
    
    echo "🔄 Migration $version: $description"
    
    if sqlite3 "$DB_PATH" "$sql"; then
        echo "✅ Migration $version completed"
        
        # Log migration
        sqlite3 "$DB_PATH" "INSERT OR IGNORE INTO schema_migrations (version, description, applied_at) VALUES ('$version', '$description', datetime('now'));"
    else
        echo "❌ Migration $version failed"
        exit 1
    fi
}

# Create migrations table if it doesn't exist
echo "🗄️  Creating migrations table..."
sqlite3 "$DB_PATH" "
CREATE TABLE IF NOT EXISTS schema_migrations (
    version TEXT PRIMARY KEY,
    description TEXT NOT NULL,
    applied_at DATETIME DEFAULT CURRENT_TIMESTAMP
);"

# Check which migrations have been applied
APPLIED_MIGRATIONS=$(sqlite3 "$DB_PATH" "SELECT version FROM schema_migrations;" 2>/dev/null || echo "")
echo "Applied migrations: $APPLIED_MIGRATIONS"

# Migration 1: Add performance indexes
if ! echo "$APPLIED_MIGRATIONS" | grep -q "001_performance_indexes"; then
    run_migration "001_performance_indexes" "Add performance indexes" "
    CREATE INDEX IF NOT EXISTS idx_files_owner_pubkey ON files(owner_pubkey);
    CREATE INDEX IF NOT EXISTS idx_files_storage_type ON files(storage_type);
    CREATE INDEX IF NOT EXISTS idx_files_access_level ON files(access_level);
    CREATE INDEX IF NOT EXISTS idx_files_size ON files(size);
    CREATE INDEX IF NOT EXISTS idx_files_last_access ON files(last_access);
    CREATE INDEX IF NOT EXISTS idx_chunks_chunk_hash ON chunks(chunk_hash);
    CREATE INDEX IF NOT EXISTS idx_users_storage_used ON users(storage_used);
    "
else
    echo "⏭️  Skipping migration 001_performance_indexes (already applied)"
fi

# Migration 2: Add monitoring columns
if ! echo "$APPLIED_MIGRATIONS" | grep -q "002_monitoring_columns"; then
    run_migration "002_monitoring_columns" "Add monitoring and metrics columns" "
    ALTER TABLE files ADD COLUMN download_count INTEGER DEFAULT 0;
    ALTER TABLE files ADD COLUMN stream_count INTEGER DEFAULT 0;
    ALTER TABLE users ADD COLUMN bandwidth_used INTEGER DEFAULT 0;
    ALTER TABLE users ADD COLUMN api_requests INTEGER DEFAULT 0;
    CREATE INDEX IF NOT EXISTS idx_files_download_count ON files(download_count);
    CREATE INDEX IF NOT EXISTS idx_files_stream_count ON files(stream_count);
    "
else
    echo "⏭️  Skipping migration 002_monitoring_columns (already applied)"
fi

# Migration 3: Add cache tables
if ! echo "$APPLIED_MIGRATIONS" | grep -q "003_cache_tables"; then
    run_migration "003_cache_tables" "Add cache management tables" "
    CREATE TABLE IF NOT EXISTS cache_entries (
        cache_key TEXT PRIMARY KEY,
        cache_value BLOB,
        cache_type TEXT NOT NULL,
        created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
        expires_at DATETIME,
        hit_count INTEGER DEFAULT 0
    );
    CREATE INDEX IF NOT EXISTS idx_cache_entries_type ON cache_entries(cache_type);
    CREATE INDEX IF NOT EXISTS idx_cache_entries_expires ON cache_entries(expires_at);
    "
else
    echo "⏭️  Skipping migration 003_cache_tables (already applied)"
fi

# Migration 4: Add rate limiting tables
if ! echo "$APPLIED_MIGRATIONS" | grep -q "004_rate_limiting"; then
    run_migration "004_rate_limiting" "Add rate limiting tracking" "
    CREATE TABLE IF NOT EXISTS rate_limit_events (
        id INTEGER PRIMARY KEY,
        client_ip TEXT NOT NULL,
        limit_type TEXT NOT NULL,
        blocked BOOLEAN DEFAULT FALSE,
        timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
    );
    CREATE INDEX IF NOT EXISTS idx_rate_limit_ip ON rate_limit_events(client_ip);
    CREATE INDEX IF NOT EXISTS idx_rate_limit_timestamp ON rate_limit_events(timestamp);
    "
else
    echo "⏭️  Skipping migration 004_rate_limiting (already applied)"
fi

# Data consistency checks
echo "🔍 Running data consistency checks..."

# Check for orphaned chunks
ORPHANED_CHUNKS=$(sqlite3 "$DB_PATH" "
SELECT COUNT(*) FROM chunks c 
LEFT JOIN files f ON c.file_hash = f.hash 
WHERE f.hash IS NULL;
")

if [ "$ORPHANED_CHUNKS" -gt 0 ]; then
    echo "⚠️  Found $ORPHANED_CHUNKS orphaned chunks"
    read -p "Remove orphaned chunks? (y/N): " -n 1 -r
    echo
    if [[ $REPLY =~ ^[Yy]$ ]]; then
        sqlite3 "$DB_PATH" "
        DELETE FROM chunks WHERE file_hash NOT IN (SELECT hash FROM files);
        "
        echo "✅ Orphaned chunks removed"
    fi
else
    echo "✅ No orphaned chunks found"
fi

# Check for expired sessions
EXPIRED_SESSIONS=$(sqlite3 "$DB_PATH" "
SELECT COUNT(*) FROM sessions 
WHERE expires_at < datetime('now');
")

if [ "$EXPIRED_SESSIONS" -gt 0 ]; then
    echo "🧹 Cleaning up $EXPIRED_SESSIONS expired sessions..."
    sqlite3 "$DB_PATH" "DELETE FROM sessions WHERE expires_at < datetime('now');"
    echo "✅ Expired sessions cleaned"
else
    echo "✅ No expired sessions found"
fi

# Update storage statistics
echo "📊 Updating storage statistics..."
sqlite3 "$DB_PATH" "
UPDATE users SET 
    storage_used = (
        SELECT COALESCE(SUM(size), 0) 
        FROM files 
        WHERE owner_pubkey = users.pubkey
    ),
    file_count = (
        SELECT COUNT(*) 
        FROM files 
        WHERE owner_pubkey = users.pubkey
    );
"
echo "✅ Storage statistics updated"

# Vacuum database for performance
echo "🧹 Optimizing database..."
sqlite3 "$DB_PATH" "VACUUM;"
sqlite3 "$DB_PATH" "ANALYZE;"
echo "✅ Database optimized"

# Final validation
echo "🔍 Final validation..."

# Check table integrity
INTEGRITY_CHECK=$(sqlite3 "$DB_PATH" "PRAGMA integrity_check;")
if [ "$INTEGRITY_CHECK" = "ok" ]; then
    echo "✅ Database integrity check passed"
else
    echo "❌ Database integrity check failed: $INTEGRITY_CHECK"
    FAILED_CHECKS=$((FAILED_CHECKS + 1))
fi

# Check foreign key constraints
FK_CHECK=$(sqlite3 "$DB_PATH" "PRAGMA foreign_key_check;")
if [ -z "$FK_CHECK" ]; then
    echo "✅ Foreign key constraints valid"
else
    echo "⚠️  Foreign key constraint violations found: $FK_CHECK"
fi

echo ""
echo "📊 Migration Summary"
echo "==================="
echo "Total checks: $TOTAL_CHECKS"
echo "Passed:       $PASSED_CHECKS"
echo "Failed:       $FAILED_CHECKS"

if [ $FAILED_CHECKS -eq 0 ]; then
    echo ""
    echo "🎉 All migrations and checks completed successfully!"
    echo "✅ Database is healthy and up-to-date"
    exit 0
else
    echo ""
    echo "⚠️  Some checks failed"
    echo "💾 Backup available at: $BACKUP_FILE"
    echo "🔧 Please investigate and fix issues"
    exit 1
fi