#!/usr/bin/env node

/**
 * Mock Server CLI Tool
 * 
 * Command-line interface for managing the SPORE UI mock server
 * with different configurations and scenarios
 */

const { spawn } = require('child_process');
const path = require('path');
const { getMockConfig, listMockConfigs, createCustomConfig } = require('./mock-configs');

// Colors for console output
const colors = {
  reset: '\x1b[0m',
  bright: '\x1b[1m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  magenta: '\x1b[35m',
  cyan: '\x1b[36m'
};

function colorize(text, color) {
  return `${colors[color]}${text}${colors.reset}`;
}

function printHeader() {
  console.log(colorize('🚀 SPORE UI Mock Server CLI', 'cyan'));
  console.log(colorize('=============================', 'cyan'));
  console.log('');
}

function printHelp() {
  console.log('Usage: node mock-cli.js <command> [options]');
  console.log('');
  console.log('Commands:');
  console.log('  start [config]     Start mock server with specified config');
  console.log('  list               List available configurations');
  console.log('  info <config>      Show detailed info about a configuration');
  console.log('  help               Show this help message');
  console.log('');
  console.log('Available Configurations:');
  listMockConfigs().forEach(config => {
    console.log(`  ${colorize(config.name, 'green')} - ${config.description} (${config.nodeCount} nodes)`);
  });
  console.log('');
  console.log('Examples:');
  console.log('  node mock-cli.js start healthy');
  console.log('  node mock-cli.js start degraded');
  console.log('  node mock-cli.js list');
  console.log('  node mock-cli.js info large');
}

function printConfigInfo(configName) {
  const config = getMockConfig(configName);
  
  console.log(colorize(`📋 Configuration: ${config.name}`, 'blue'));
  console.log(colorize('='.repeat(50), 'blue'));
  console.log(`Description: ${config.description}`);
  console.log(`Nodes: ${config.nodes.length}`);
  console.log('');
  
  if (config.nodes.length > 0) {
    console.log(colorize('🌐 Mock Nodes:', 'yellow'));
    config.nodes.forEach((node, index) => {
      const statusColor = node.status === 'ACTIVE' ? 'green' : 
                         node.status === 'INACTIVE' ? 'yellow' : 'red';
      console.log(`  ${index + 1}. ${colorize(node.hostname, 'cyan')} (${node.ip}) - ${colorize(node.status, statusColor)}`);
    });
    console.log('');
  }
  
  console.log(colorize('⚙️  Simulation Settings:', 'yellow'));
  console.log(`  Time Progression: ${config.simulation.enableTimeProgression ? colorize('Enabled', 'green') : colorize('Disabled', 'red')}`);
  console.log(`  Random Failures: ${config.simulation.enableRandomFailures ? colorize('Enabled', 'green') : colorize('Disabled', 'red')}`);
  if (config.simulation.enableRandomFailures) {
    console.log(`  Failure Rate: ${(config.simulation.failureRate * 100).toFixed(1)}%`);
  }
  console.log(`  Update Interval: ${config.simulation.updateInterval}ms`);
  console.log(`  Primary Rotation: ${config.simulation.primaryNodeRotation ? colorize('Enabled', 'green') : colorize('Disabled', 'red')}`);
  if (config.simulation.primaryNodeRotation) {
    console.log(`  Rotation Interval: ${config.simulation.rotationInterval}ms`);
  }
  console.log('');
}

function startMockServer(configName) {
  const config = getMockConfig(configName);
  
  console.log(colorize(`🚀 Starting mock server with '${config.name}' configuration...`, 'green'));
  console.log('');
  
  // Set environment variables for the mock server
  const env = {
    ...process.env,
    MOCK_CONFIG: configName,
    MOCK_PORT: process.env.MOCK_PORT || '3002'
  };
  
  // Start the mock server
  const mockServerPath = path.join(__dirname, 'mock-server.js');
  const child = spawn('node', [mockServerPath], {
    env: env,
    stdio: 'inherit',
    cwd: path.join(__dirname, '..')
  });
  
  // Handle process termination
  process.on('SIGINT', () => {
    console.log(colorize('\n\n🛑 Stopping mock server...', 'yellow'));
    child.kill('SIGINT');
    process.exit(0);
  });
  
  child.on('close', (code) => {
    if (code !== 0) {
      console.log(colorize(`\n❌ Mock server exited with code ${code}`, 'red'));
    } else {
      console.log(colorize('\n✅ Mock server stopped gracefully', 'green'));
    }
  });
  
  child.on('error', (error) => {
    console.error(colorize(`\n❌ Failed to start mock server: ${error.message}`, 'red'));
    process.exit(1);
  });
}

function listConfigurations() {
  console.log(colorize('📋 Available Mock Configurations', 'blue'));
  console.log(colorize('================================', 'blue'));
  console.log('');
  
  const configs = listMockConfigs();
  configs.forEach(config => {
    console.log(colorize(`🔧 ${config.displayName}`, 'green'));
    console.log(`   Key: ${colorize(config.name, 'cyan')}`);
    console.log(`   Description: ${config.description}`);
    console.log(`   Nodes: ${config.nodeCount}`);
    console.log('');
  });
  
  console.log(colorize('💡 Usage:', 'yellow'));
  console.log('  node mock-cli.js start <config-key>');
  console.log('  node mock-cli.js info <config-key>');
  console.log('');
}

// Main CLI logic
function main() {
  const args = process.argv.slice(2);
  const command = args[0];
  const configName = args[1];
  
  printHeader();
  
  switch (command) {
    case 'start':
      if (!configName) {
        console.log(colorize('❌ Error: Configuration name required', 'red'));
        console.log('Usage: node mock-cli.js start <config-name>');
        console.log('Run "node mock-cli.js list" to see available configurations');
        process.exit(1);
      }
      
      const config = getMockConfig(configName);
      if (!config) {
        console.log(colorize(`❌ Error: Unknown configuration '${configName}'`, 'red'));
        console.log('Run "node mock-cli.js list" to see available configurations');
        process.exit(1);
      }
      
      printConfigInfo(configName);
      startMockServer(configName);
      break;
      
    case 'list':
      listConfigurations();
      break;
      
    case 'info':
      if (!configName) {
        console.log(colorize('❌ Error: Configuration name required', 'red'));
        console.log('Usage: node mock-cli.js info <config-name>');
        console.log('Run "node mock-cli.js list" to see available configurations');
        process.exit(1);
      }
      
      const infoConfig = getMockConfig(configName);
      if (!infoConfig) {
        console.log(colorize(`❌ Error: Unknown configuration '${configName}'`, 'red'));
        console.log('Run "node mock-cli.js list" to see available configurations');
        process.exit(1);
      }
      
      printConfigInfo(configName);
      break;
      
    case 'help':
    case '--help':
    case '-h':
      printHelp();
      break;
      
    default:
      if (!command) {
        console.log(colorize('❌ Error: Command required', 'red'));
        console.log('');
        printHelp();
      } else {
        console.log(colorize(`❌ Error: Unknown command '${command}'`, 'red'));
        console.log('');
        printHelp();
      }
      process.exit(1);
  }
}

// Run the CLI
if (require.main === module) {
  main();
}

module.exports = {
  getMockConfig,
  listMockConfigs,
  printConfigInfo,
  startMockServer
};
