#!/usr/bin/env node

/**
 * Backup management script
 * Usage: node scripts/backup.js <command> [options]
 */

const { backupManager, backupScheduler, DisasterRecovery } = require('../src/lib/backup.ts');

// Parse command line arguments
const args = process.argv.slice(2);
const command = args[0];

async function main() {
  try {
    switch (command) {
      case 'create':
        await createBackup();
        break;
      case 'restore':
        await restoreBackup();
        break;
      case 'list':
        await listBackups();
        break;
      case 'cleanup':
        await cleanupBackups();
        break;
      case 'schedule':
        await startScheduler();
        break;
      case 'verify':
        await verifyIntegrity();
        break;
      case 'disaster-recovery':
        await createDisasterRecoveryBackup();
        break;
      default:
        showUsage();
    }
  } catch (error) {
    console.error('Error:', error.message);
    process.exit(1);
  }
}

async function createBackup() {
  const type = args[1] || 'daily';
  
  if (!['daily', 'weekly', 'monthly'].includes(type)) {
    console.error('Invalid backup type. Use: daily, weekly, or monthly');
    process.exit(1);
  }

  console.log(`Creating ${type} backup...`);
  const backup = await backupManager.createBackup(type);
  
  console.log('Backup created successfully!');
  console.log(`ID: ${backup.id}`);
  console.log(`Size: ${(backup.size / 1024 / 1024).toFixed(2)} MB`);
  console.log(`Tables: ${backup.tables.join(', ')}`);
  console.log(`Checksum: ${backup.checksum}`);
}

async function restoreBackup() {
  const backupId = args[1];
  const confirmFlag = args.includes('--confirm');
  const dryRun = args.includes('--dry-run');
  const tables = args.includes('--tables') ? 
    args[args.indexOf('--tables') + 1].split(',') : undefined;

  if (!backupId) {
    console.error('Backup ID is required');
    console.log('Usage: node scripts/backup.js restore <backup-id> [--confirm] [--dry-run] [--tables table1,table2]');
    process.exit(1);
  }

  if (!confirmFlag && !dryRun) {
    console.error('WARNING: This will overwrite existing data!');
    console.error('Use --confirm to proceed or --dry-run to simulate');
    process.exit(1);
  }

  console.log(`${dryRun ? 'Simulating' : 'Starting'} restore from backup: ${backupId}`);
  
  await backupManager.restoreBackup(backupId, {
    tables,
    dryRun,
    confirmRestore: confirmFlag
  });

  console.log(`Restore ${dryRun ? 'simulation' : 'process'} completed successfully!`);
}

async function listBackups() {
  console.log('Listing available backups...');
  const backups = await backupManager.listBackups();

  if (backups.length === 0) {
    console.log('No backups found');
    return;
  }

  console.log('\nAvailable backups:');
  console.log('─'.repeat(80));
  
  for (const backup of backups) {
    const date = new Date(backup.timestamp).toLocaleString();
    const size = (backup.size / 1024 / 1024).toFixed(2);
    const status = backup.status === 'completed' ? '✓' : 
                   backup.status === 'failed' ? '✗' : '⏳';
    
    console.log(`${status} ${backup.id}`);
    console.log(`   Type: ${backup.type}`);
    console.log(`   Date: ${date}`);
    console.log(`   Size: ${size} MB`);
    console.log(`   Tables: ${backup.tables.length}`);
    console.log('');
  }
}

async function cleanupBackups() {
  console.log('Cleaning up old backups...');
  await backupManager.cleanupBackups();
  console.log('Cleanup completed!');
}

async function startScheduler() {
  console.log('Starting backup scheduler...');
  backupScheduler.startScheduledBackups();
  
  console.log('Backup scheduler is running. Press Ctrl+C to stop.');
  
  // Keep the process running
  process.on('SIGINT', () => {
    console.log('\nStopping backup scheduler...');
    backupScheduler.stopScheduledBackups();
    process.exit(0);
  });
  
  // Keep alive
  setInterval(() => {
    console.log(`Scheduler running... ${new Date().toLocaleString()}`);
  }, 60000); // Log every minute
}

async function verifyIntegrity() {
  console.log('Verifying system integrity...');
  const result = await DisasterRecovery.verifySystemIntegrity();
  
  console.log(`\nSystem Status: ${result.status.toUpperCase()}`);
  console.log('─'.repeat(50));
  
  for (const check of result.checks) {
    const icon = check.status === 'pass' ? '✓' : '✗';
    console.log(`${icon} ${check.name}: ${check.message}`);
  }
  
  if (result.status !== 'healthy') {
    console.log('\n⚠️  System requires attention!');
    process.exit(1);
  } else {
    console.log('\n✅ System is healthy');
  }
}

async function createDisasterRecoveryBackup() {
  const label = args[1] || `emergency-${Date.now()}`;
  
  console.log(`Creating disaster recovery backup: ${label}`);
  const backup = await DisasterRecovery.createPointInTimeBackup(label);
  
  console.log('Disaster recovery backup created successfully!');
  console.log(`ID: ${backup.id}`);
  console.log(`Size: ${(backup.size / 1024 / 1024).toFixed(2)} MB`);
  console.log(`Location: disaster-recovery/${label}`);
}

function showUsage() {
  console.log(`
Backup Management Script

Usage: node scripts/backup.js <command> [options]

Commands:
  create [type]              Create a new backup (daily|weekly|monthly)
  restore <id> [options]     Restore from backup
  list                       List available backups
  cleanup                    Remove old backups according to retention policy
  schedule                   Start automated backup scheduler
  verify                     Verify system integrity
  disaster-recovery [label]  Create emergency backup

Restore options:
  --confirm                  Confirm destructive restore operation
  --dry-run                  Simulate restore without making changes
  --tables table1,table2     Only restore specified tables

Examples:
  node scripts/backup.js create daily
  node scripts/backup.js restore daily-1234567890 --confirm
  node scripts/backup.js restore daily-1234567890 --dry-run --tables users,events
  node scripts/backup.js disaster-recovery pre-migration
  node scripts/backup.js verify
`);
}

// Run the main function
main().catch(console.error);