<?php
/**
 * XCHANGE 2025: MULTIPLE DELEGATE TYPES MIGRATION
 * 
 * This migration converts the single DELEGATE_PASS product into multiple
 * delegate type products, enabling users to select multiple delegate types
 * in a single registration.
 * 
 * Usage: php migrate_multiple_delegate_types.php [--rollback] [--dry-run]
 * 
 * Options:
 *   --rollback    Rollback the migration
 *   --dry-run     Show what would be done without executing
 *   --force       Skip confirmation prompts
 */

require_once 'db_config.php';

class MultipleDelegateTypesMigration {
    private $pdo;
    private $dryRun = false;
    private $rollback = false;
    private $force = false;
    private $migrationId;
    
    // Define delegate types to create
    private $delegateTypes = [
        [
            'product_code' => 'DELEGATE_EARLY_BIRD',
            'name' => 'Early Bird Delegate',
            'description' => 'Discounted delegate pass for early registrations. Access to all sessions, exhibits, and networking.',
            'base_price' => 450.00,
            'total_stock' => null,
            'max_per_registration' => 50,
            'display_order' => 1,
            'metadata' => [
                'type' => 'early_bird',
                'eligibility' => ['general'],
                'approval_required' => false,
                'description_short' => 'Early registration discount'
            ]
        ],
        [
            'product_code' => 'DELEGATE_STANDARD',
            'name' => 'Standard Delegate',
            'description' => 'Regular delegate pass. Access to all sessions, exhibits, and networking.',
            'base_price' => 550.00,
            'total_stock' => null,
            'max_per_registration' => 50,
            'display_order' => 2,
            'metadata' => [
                'type' => 'standard',
                'eligibility' => ['general'],
                'approval_required' => false,
                'description_short' => 'Regular registration'
            ]
        ],
        [
            'product_code' => 'DELEGATE_STUDENT',
            'name' => 'Student Delegate',
            'description' => 'Discounted pass for students. Access to all sessions, exhibits, and networking. Student verification may be required.',
            'base_price' => 300.00,
            'total_stock' => null,
            'max_per_registration' => 50,
            'display_order' => 3,
            'metadata' => [
                'type' => 'student',
                'eligibility' => ['students'],
                'approval_required' => false,
                'description_short' => 'Student discount',
                'verification_note' => 'Student ID may be required at event'
            ]
        ],
        [
            'product_code' => 'DELEGATE_SPEAKER',
            'name' => 'Speaker',
            'description' => 'Complimentary pass for event speakers. Full access to all sessions, exhibits, and networking.',
            'base_price' => 0.00,
            'total_stock' => 50,
            'max_per_registration' => 20,
            'display_order' => 4,
            'metadata' => [
                'type' => 'speaker',
                'eligibility' => ['speakers'],
                'approval_required' => false,
                'complimentary' => true,
                'description_short' => 'Complimentary for speakers'
            ]
        ],
        [
            'product_code' => 'DELEGATE_VIP',
            'name' => 'VIP Delegate',
            'description' => 'Premium delegate experience with exclusive access to VIP areas, priority seating, and enhanced networking opportunities.',
            'base_price' => 800.00,
            'total_stock' => 30,
            'max_per_registration' => 20,
            'display_order' => 5,
            'metadata' => [
                'type' => 'vip',
                'eligibility' => ['general'],
                'approval_required' => false,
                'premium' => true,
                'description_short' => 'Premium experience with exclusive access'
            ]
        ],
        [
            'product_code' => 'DELEGATE_ORGANIZER',
            'name' => 'Event Organizer',
            'description' => 'Complimentary pass for event organizers and staff. Full access to all sessions, exhibits, and networking.',
            'base_price' => 0.00,
            'total_stock' => 20,
            'max_per_registration' => 10,
            'display_order' => 6,
            'metadata' => [
                'type' => 'organizer',
                'eligibility' => ['organizers'],
                'approval_required' => false,
                'complimentary' => true,
                'description_short' => 'Complimentary for organizers'
            ]
        ]
    ];
    
    // Pricing tiers to create
    private $pricingTiers = [
        'DELEGATE_EARLY_BIRD' => [
            ['tier_name' => 'Super Early Bird', 'price' => 400.00, 'valid_from' => '2025-06-01 00:00:00', 'valid_until' => '2025-07-31 23:59:59'],
            ['tier_name' => 'Early Bird Extended', 'price' => 475.00, 'valid_from' => '2025-08-01 00:00:00', 'valid_until' => '2025-09-30 23:59:59']
        ],
        'DELEGATE_STANDARD' => [
            ['tier_name' => 'Late Registration', 'price' => 600.00, 'valid_from' => '2025-10-01 00:00:00', 'valid_until' => '2025-11-25 23:59:59']
        ],
        'DELEGATE_VIP' => [
            ['tier_name' => 'VIP Early Bird', 'price' => 750.00, 'valid_from' => '2025-06-01 00:00:00', 'valid_until' => '2025-08-31 23:59:59']
        ]
    ];
    
    public function __construct() {
        $this->pdo = getDBConnection();
        $this->migrationId = 'multiple_delegate_types_' . date('Y_m_d_H_i_s');
        
        // Parse command line arguments
        global $argv;
        if (isset($argv)) {
            $this->dryRun = in_array('--dry-run', $argv);
            $this->rollback = in_array('--rollback', $argv);
            $this->force = in_array('--force', $argv);
        }
        
        // Production safety check (skip for web interface)
        if (php_sapi_name() === 'cli') {
            $this->checkProductionEnvironment();
        }
    }
    
    public function setDryRun($dryRun) {
        $this->dryRun = $dryRun;
    }
    
    public function setForce($force) {
        $this->force = $force;
    }
    
    public function setRollback($rollback) {
        $this->rollback = $rollback;
    }
    
    private function checkProductionEnvironment() {
        // Check if this looks like a production environment
        $isProduction = false;
        
        // Check database name for production indicators
        $stmt = $this->pdo->prepare("SELECT DATABASE() as db_name");
        $stmt->execute();
        $dbName = $stmt->fetch()['db_name'];
        
        if (strpos(strtolower($dbName), 'live') !== false || 
            strpos(strtolower($dbName), 'prod') !== false ||
            strpos(strtolower($dbName), 'production') !== false) {
            $isProduction = true;
        }
        
        // Check for high registration count (likely production)
        $stmt = $this->pdo->prepare("SELECT COUNT(*) as count FROM registrations");
        $stmt->execute();
        $regCount = $stmt->fetch()['count'];
        
        if ($regCount > 50) {
            $isProduction = true;
        }
        
        if ($isProduction && !$this->force && !$this->dryRun) {
            $this->log("⚠️  PRODUCTION ENVIRONMENT DETECTED!");
            $this->log("Database: {$dbName}");
            $this->log("Registrations: {$regCount}");
            $this->log("");
            $this->log("STRONGLY RECOMMENDED:");
            $this->log("1. Create a database backup first");
            $this->log("2. Run with --dry-run to test first");
            $this->log("3. Run during maintenance window");
            $this->log("");
            $this->log("Use --force to proceed anyway (not recommended without backup)");
            
            echo "\nThis appears to be a PRODUCTION environment.\n";
            echo "Have you created a database backup? (y/N): ";
            $handle = fopen("php://stdin", "r");
            $line = fgets($handle);
            fclose($handle);
            
            if (trim(strtolower($line)) !== 'y') {
                $this->log("Migration cancelled. Please create a backup first.");
                exit(1);
            }
        }
    }
    
    public function run() {
        try {
            $this->log("=== MULTIPLE DELEGATE TYPES MIGRATION ===");
            $this->log("Migration ID: {$this->migrationId}");
            $this->log("Dry Run: " . ($this->dryRun ? 'YES' : 'NO'));
            $this->log("Rollback: " . ($this->rollback ? 'YES' : 'NO'));
            
            if ($this->rollback) {
                return $this->runRollback();
            } else {
                return $this->runMigration();
            }
            
        } catch (Exception $e) {
            $this->log("ERROR: " . $e->getMessage(), 'error');
            $this->log("Migration failed. Database should be in original state due to transaction rollback.");
            return false;
        }
    }
    
    private function runMigration() {
        // Pre-migration checks
        $this->log("\n--- PRE-MIGRATION CHECKS ---");
        if (!$this->preflightChecks()) {
            throw new Exception("Pre-migration checks failed");
        }
        
        // Confirm with user unless --force is used
        if (!$this->force && !$this->dryRun) {
            $this->log("\nThis migration will:");
            $this->log("- Create 6 new delegate type products");
            $this->log("- Migrate existing registration data");
            $this->log("- Deactivate old DELEGATE_PASS product");
            $this->log("- Create sample pricing tiers");
            
            echo "\nDo you want to continue? (y/N): ";
            $handle = fopen("php://stdin", "r");
            $line = fgets($handle);
            fclose($handle);
            
            if (trim(strtolower($line)) !== 'y') {
                $this->log("Migration cancelled by user.");
                return false;
            }
        }
        
        if ($this->dryRun) {
            $this->log("\n--- DRY RUN MODE - NO CHANGES WILL BE MADE ---");
        }
        
        // Start transaction
        if (!$this->dryRun) {
            $this->pdo->beginTransaction();
        }
        
        try {
            // Step 1: Create new delegate products
            $this->log("\n--- STEP 1: CREATE DELEGATE PRODUCTS ---");
            $productIds = $this->createDelegateProducts();
            
            // Step 2: Create pricing tiers
            $this->log("\n--- STEP 2: CREATE PRICING TIERS ---");
            $this->createPricingTiers($productIds);
            
            // Step 3: Migrate existing registration data
            $this->log("\n--- STEP 3: MIGRATE EXISTING DATA ---");
            $this->migrateExistingData($productIds);
            
            // Step 4: Deactivate old product
            $this->log("\n--- STEP 4: DEACTIVATE OLD PRODUCT ---");
            $this->deactivateOldProduct();
            
            // Step 5: Update frontend configuration
            $this->log("\n--- STEP 5: UPDATE FRONTEND CONFIG ---");
            $this->updateFrontendConfig();
            
            // Step 6: Log migration
            $this->log("\n--- STEP 6: LOG MIGRATION ---");
            $this->logMigration();
            
            // Commit transaction
            if (!$this->dryRun) {
                $this->pdo->commit();
                $this->log("\n✅ MIGRATION COMPLETED SUCCESSFULLY!");
            } else {
                $this->log("\n✅ DRY RUN COMPLETED - No changes made");
            }
            
            // Post-migration verification
            $this->log("\n--- POST-MIGRATION VERIFICATION ---");
            $this->verifyMigration();
            
            return true;
            
        } catch (Exception $e) {
            if (!$this->dryRun) {
                $this->pdo->rollback();
            }
            throw $e;
        }
    }
    
    private function preflightChecks() {
        $this->log("Checking database connection...");
        if (!$this->pdo) {
            $this->log("❌ Database connection failed", 'error');
            return false;
        }
        $this->log("✅ Database connection OK");
        
        $this->log("Checking if old DELEGATE_PASS product exists...");
        $stmt = $this->pdo->prepare("SELECT id, name, is_active FROM products WHERE product_code = 'DELEGATE_PASS'");
        $stmt->execute();
        $oldProduct = $stmt->fetch();
        
        if (!$oldProduct) {
            $this->log("❌ Old DELEGATE_PASS product not found", 'error');
            return false;
        }
        $this->log("✅ Found DELEGATE_PASS product (ID: {$oldProduct['id']}, Active: {$oldProduct['is_active']})");
        
        $this->log("Checking for existing registrations...");
        $stmt = $this->pdo->prepare("SELECT COUNT(*) as count FROM registrations");
        $stmt->execute();
        $regCount = $stmt->fetch()['count'];
        $this->log("✅ Found {$regCount} existing registrations");
        
        $this->log("Checking if new delegate products already exist...");
        $existingProducts = [];
        foreach ($this->delegateTypes as $type) {
            $stmt = $this->pdo->prepare("SELECT id, name, is_active FROM products WHERE product_code = ?");
            $stmt->execute([$type['product_code']]);
            $existing = $stmt->fetch();
            if ($existing) {
                $existingProducts[] = [
                    'code' => $type['product_code'],
                    'id' => $existing['id'],
                    'name' => $existing['name'],
                    'active' => $existing['is_active']
                ];
            }
        }
        
        if (!empty($existingProducts)) {
            $this->log("⚠️  WARNING: Some delegate products already exist:");
            foreach ($existingProducts as $product) {
                $status = $product['active'] ? 'Active' : 'Inactive';
                $this->log("    - {$product['code']} (ID: {$product['id']}) - {$product['name']} - {$status}");
            }
            $this->log("Migration will skip creating existing products.");
        } else {
            $this->log("✅ No conflicting delegate products found");
        }
        
        return true;
    }
    
    private function createDelegateProducts() {
        $productIds = [];
        
        foreach ($this->delegateTypes as $type) {
            $this->log("Creating product: {$type['name']} ({$type['product_code']})");
            
            // Check if product already exists
            $stmt = $this->pdo->prepare("SELECT id FROM products WHERE product_code = ?");
            $stmt->execute([$type['product_code']]);
            $existing = $stmt->fetch();
            
            if ($existing) {
                $this->log("  ⚠️  Product already exists (ID: {$existing['id']}), skipping");
                $productIds[$type['product_code']] = $existing['id'];
                continue;
            }
            
            if (!$this->dryRun) {
                $stmt = $this->pdo->prepare("
                    INSERT INTO products (
                        category_id, product_code, name, description, base_price, currency,
                        total_stock, is_active, requires_approval, max_per_registration,
                        display_order, metadata, created_at, updated_at
                    ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())
                ");
                
                $stmt->execute([
                    3, // category_id for Delegate Pass
                    $type['product_code'],
                    $type['name'],
                    $type['description'],
                    $type['base_price'],
                    'USD',
                    $type['total_stock'],
                    1, // is_active
                    0, // requires_approval
                    $type['max_per_registration'],
                    $type['display_order'],
                    json_encode($type['metadata'])
                ]);
                
                $productIds[$type['product_code']] = $this->pdo->lastInsertId();
                $this->log("  ✅ Created product (ID: {$productIds[$type['product_code']]})");
            } else {
                $productIds[$type['product_code']] = 'DRY_RUN_ID';
                $this->log("  ✅ Would create product: {$type['name']}");
            }
        }
        
        return $productIds;
    }
    
    private function createPricingTiers($productIds) {
        foreach ($this->pricingTiers as $productCode => $tiers) {
            if (!isset($productIds[$productCode])) {
                $this->log("  ⚠️  Product {$productCode} not found, skipping pricing tiers");
                continue;
            }
            
            $productId = $productIds[$productCode];
            $this->log("Creating pricing tiers for {$productCode}...");
            
            foreach ($tiers as $tier) {
                $this->log("  - {$tier['tier_name']}: \${$tier['price']}");
                
                if (!$this->dryRun) {
                    $stmt = $this->pdo->prepare("
                        INSERT INTO product_pricing (
                            product_id, pricing_tier, price, valid_from, valid_until, is_active, created_at
                        ) VALUES (?, ?, ?, ?, ?, ?, NOW())
                    ");
                    
                    $stmt->execute([
                        $productId,
                        $tier['tier_name'],
                        $tier['price'],
                        $tier['valid_from'],
                        $tier['valid_until'],
                        1
                    ]);
                }
            }
        }
    }
    
    private function migrateExistingData($productIds) {
        // Get existing registrations with delegate data
        $stmt = $this->pdo->prepare("
            SELECT r.id, r.registration_number, r.delegate_type, r.delegate_count,
                   rp.id as reg_product_id, rp.product_id as old_product_id
            FROM registrations r
            LEFT JOIN registration_products rp ON r.id = rp.registration_id
            JOIN products p ON rp.product_id = p.id
            WHERE p.product_code = 'DELEGATE_PASS'
        ");
        $stmt->execute();
        $registrations = $stmt->fetchAll();
        
        $this->log("Found " . count($registrations) . " registrations to migrate");
        
        if (count($registrations) === 0) {
            $this->log("✅ No registrations to migrate");
            return;
        }
        
        foreach ($registrations as $reg) {
            $newProductCode = ($reg['delegate_type'] === 'earlyBird') ? 'DELEGATE_EARLY_BIRD' : 'DELEGATE_STANDARD';
            
            if (!isset($productIds[$newProductCode])) {
                $this->log("  ⚠️  Target product {$newProductCode} not found for registration {$reg['registration_number']}, skipping");
                continue;
            }
            
            $newProductId = $productIds[$newProductCode];
            
            $this->log("  Migrating registration {$reg['registration_number']}: {$reg['delegate_type']} -> {$newProductCode}");
            
            if (!$this->dryRun) {
                $stmt = $this->pdo->prepare("
                    UPDATE registration_products 
                    SET product_id = ? 
                    WHERE id = ?
                ");
                $stmt->execute([$newProductId, $reg['reg_product_id']]);
                
                // Verify the update
                $verifyStmt = $this->pdo->prepare("SELECT product_id FROM registration_products WHERE id = ?");
                $verifyStmt->execute([$reg['reg_product_id']]);
                $updatedProductId = $verifyStmt->fetch()['product_id'];
                
                if ($updatedProductId != $newProductId) {
                    throw new Exception("Failed to update registration product for {$reg['registration_number']}");
                }
            }
        }
        
        $this->log("✅ Registration data migration completed");
    }
    
    private function deactivateOldProduct() {
        $this->log("Deactivating old DELEGATE_PASS product...");
        
        if (!$this->dryRun) {
            $stmt = $this->pdo->prepare("
                UPDATE products 
                SET is_active = 0, 
                    name = 'Delegates (Legacy - Migrated)',
                    updated_at = NOW()
                WHERE product_code = 'DELEGATE_PASS'
            ");
            $stmt->execute();
            $this->log("✅ Old product deactivated");
        } else {
            $this->log("✅ Would deactivate old DELEGATE_PASS product");
        }
    }
    
    private function updateFrontendConfig() {
        $this->log("Updating frontend configuration...");
        
        if (!$this->dryRun) {
            try {
                // Check if frontend_config table exists
                $stmt = $this->pdo->prepare("SHOW TABLES LIKE 'frontend_config'");
                $stmt->execute();
                $tableExists = $stmt->fetch();
                
                if ($tableExists) {
                    $stmt = $this->pdo->prepare("
                        INSERT IGNORE INTO frontend_config (page_section, category_id, display_mode, created_at, updated_at)
                        VALUES ('delegate_passes', 3, 'category', NOW(), NOW())
                        ON DUPLICATE KEY UPDATE 
                            display_mode = 'category',
                            updated_at = NOW()
                    ");
                    $stmt->execute();
                    $this->log("✅ Frontend configuration updated");
                } else {
                    $this->log("⚠️  frontend_config table doesn't exist, skipping (not critical)");
                }
            } catch (Exception $e) {
                $this->log("⚠️  Frontend config update failed (not critical): " . $e->getMessage());
            }
        } else {
            $this->log("✅ Would update frontend configuration");
        }
    }
    
    private function logMigration() {
        if (!$this->dryRun) {
            $stmt = $this->pdo->prepare("
                INSERT INTO admin_activity_log (
                    admin_user_id, action, target_type, details, ip_address, created_at
                ) VALUES (?, ?, ?, ?, ?, NOW())
            ");
            
            $stmt->execute([
                1, // admin user id
                'SYSTEM_MIGRATION',
                'products',
                "Multiple Delegate Types Migration ({$this->migrationId}): Created 6 new delegate type products and migrated existing registration data",
                '127.0.0.1'
            ]);
        }
    }
    
    private function verifyMigration() {
        $this->log("Verifying migration results...");
        
        // Check new products
        $stmt = $this->pdo->prepare("
            SELECT COUNT(*) as count 
            FROM products 
            WHERE product_code IN ('DELEGATE_EARLY_BIRD', 'DELEGATE_STANDARD', 'DELEGATE_STUDENT', 'DELEGATE_SPEAKER', 'DELEGATE_VIP', 'DELEGATE_ORGANIZER')
            AND is_active = 1
        ");
        $stmt->execute();
        $newProductCount = $stmt->fetch()['count'];
        $this->log("✅ New delegate products created: {$newProductCount}/6");
        
        // Check pricing tiers
        $stmt = $this->pdo->prepare("
            SELECT COUNT(*) as count 
            FROM product_pricing pp
            JOIN products p ON pp.product_id = p.id
            WHERE p.product_code IN ('DELEGATE_EARLY_BIRD', 'DELEGATE_STANDARD', 'DELEGATE_VIP')
        ");
        $stmt->execute();
        $tierCount = $stmt->fetch()['count'];
        $this->log("✅ Pricing tiers created: {$tierCount}");
        
        // Check old product status
        $stmt = $this->pdo->prepare("
            SELECT is_active 
            FROM products 
            WHERE product_code = 'DELEGATE_PASS'
        ");
        $stmt->execute();
        $oldProductActive = $stmt->fetch()['is_active'];
        $this->log("✅ Old DELEGATE_PASS product deactivated: " . ($oldProductActive ? 'NO' : 'YES'));
        
        if ($newProductCount == 6 && $tierCount > 0 && !$oldProductActive) {
            $this->log("🎉 Migration verification PASSED!");
        } else {
            $this->log("⚠️  Migration verification found issues - please review");
        }
    }
    
    private function runRollback() {
        $this->log("\n--- ROLLBACK MODE ---");
        
        if (!$this->force) {
            echo "\nThis will rollback the multiple delegate types migration. Continue? (y/N): ";
            $handle = fopen("php://stdin", "r");
            $line = fgets($handle);
            fclose($handle);
            
            if (trim(strtolower($line)) !== 'y') {
                $this->log("Rollback cancelled by user.");
                return false;
            }
        }
        
        if (!$this->dryRun) {
            $this->pdo->beginTransaction();
        }
        
        try {
            // Reactivate old DELEGATE_PASS product
            $this->log("Reactivating old DELEGATE_PASS product...");
            if (!$this->dryRun) {
                $stmt = $this->pdo->prepare("UPDATE products SET is_active = 1, name = 'Delegates' WHERE product_code = 'DELEGATE_PASS'");
                $stmt->execute();
            }
            
            // Restore registration_products mappings
            $this->log("Restoring registration product mappings...");
            if (!$this->dryRun) {
                $oldProductStmt = $this->pdo->prepare("SELECT id FROM products WHERE product_code = 'DELEGATE_PASS'");
                $oldProductStmt->execute();
                $oldProductId = $oldProductStmt->fetch()['id'];
                
                $stmt = $this->pdo->prepare("
                    UPDATE registration_products rp
                    JOIN registrations r ON rp.registration_id = r.id
                    SET rp.product_id = ?
                    WHERE rp.product_id IN (
                        SELECT id FROM products WHERE product_code IN 
                        ('DELEGATE_EARLY_BIRD', 'DELEGATE_STANDARD', 'DELEGATE_STUDENT', 'DELEGATE_SPEAKER', 'DELEGATE_VIP', 'DELEGATE_ORGANIZER')
                    )
                ");
                $stmt->execute([$oldProductId]);
            }
            
            // Delete pricing tiers
            $this->log("Deleting pricing tiers...");
            if (!$this->dryRun) {
                $stmt = $this->pdo->prepare("
                    DELETE FROM product_pricing WHERE product_id IN (
                        SELECT id FROM products WHERE product_code IN 
                        ('DELEGATE_EARLY_BIRD', 'DELEGATE_STANDARD', 'DELEGATE_STUDENT', 'DELEGATE_SPEAKER', 'DELEGATE_VIP', 'DELEGATE_ORGANIZER')
                    )
                ");
                $stmt->execute();
            }
            
            // Delete new products
            $this->log("Deleting new delegate products...");
            if (!$this->dryRun) {
                $stmt = $this->pdo->prepare("
                    DELETE FROM products WHERE product_code IN 
                    ('DELEGATE_EARLY_BIRD', 'DELEGATE_STANDARD', 'DELEGATE_STUDENT', 'DELEGATE_SPEAKER', 'DELEGATE_VIP', 'DELEGATE_ORGANIZER')
                ");
                $stmt->execute();
            }
            
            if (!$this->dryRun) {
                $this->pdo->commit();
                $this->log("✅ ROLLBACK COMPLETED SUCCESSFULLY!");
            } else {
                $this->log("✅ ROLLBACK DRY RUN COMPLETED");
            }
            
            return true;
            
        } catch (Exception $e) {
            if (!$this->dryRun) {
                $this->pdo->rollback();
            }
            throw $e;
        }
    }
    
    private function log($message, $level = 'info') {
        $timestamp = date('Y-m-d H:i:s');
        $levelPrefix = strtoupper($level);
        echo "[{$timestamp}] [{$levelPrefix}] {$message}\n";
        
        // Also log to file
        $logFile = "migration_" . date('Y_m_d') . ".log";
        file_put_contents($logFile, "[{$timestamp}] [{$levelPrefix}] {$message}\n", FILE_APPEND);
    }
}

// Run migration if called directly
if (basename(__FILE__) == basename($_SERVER["SCRIPT_NAME"])) {
    $migration = new MultipleDelegateTypesMigration();
    $success = $migration->run();
    exit($success ? 0 : 1);
}
?>
