#!/usr/bin/env node

/**
 * Complete Mock Server for SPORE UI
 * 
 * This mock server provides a complete simulation of the SPORE embedded system
 * without requiring actual hardware or UDP port conflicts. It simulates:
 * - Multiple SPORE nodes with different IPs
 * - All API endpoints from the OpenAPI specification
 * - Discovery system without UDP conflicts
 * - Realistic data that changes over time
 * - Different scenarios (healthy, degraded, error states)
 */

const express = require('express');
const cors = require('cors');
const path = require('path');
const { getMockConfig } = require('./mock-configs');

// Load mock configuration
const configName = process.env.MOCK_CONFIG || 'healthy';
const baseConfig = getMockConfig(configName);

// Mock server configuration
const MOCK_CONFIG = {
  // Server settings
  port: process.env.MOCK_PORT || 3002,
  baseUrl: process.env.MOCK_BASE_URL || 'http://localhost:3002',
  
  // Load configuration from preset
  ...baseConfig
};

// Initialize Express app
const app = express();
app.use(cors({
  origin: true,
  credentials: true,
  allowedHeaders: ['Content-Type', 'Authorization']
}));

// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Mock data generators
class MockDataGenerator {
  constructor() {
    this.startTime = Date.now();
    this.nodeStates = new Map();
    this.primaryNodeIndex = 0;
    this.initializeNodeStates();
  }

  initializeNodeStates() {
    MOCK_CONFIG.nodes.forEach((node, index) => {
      this.nodeStates.set(node.ip, {
        ...node,
        freeHeap: this.generateFreeHeap(),
        uptime: 0,
        lastSeen: Date.now(),
        tasks: this.generateTasks(),
        systemInfo: this.generateSystemInfo(node),
        apiEndpoints: this.generateApiEndpoints()
      });
    });
  }

  generateFreeHeap() {
    // Simulate realistic ESP8266 memory usage
    const base = 30000;
    const variation = 20000;
    return Math.floor(base + Math.random() * variation);
  }

  generateSystemInfo(node) {
    return {
      freeHeap: this.generateFreeHeap(),
      chipId: node.chipId,
      sdkVersion: "3.1.2",
      cpuFreqMHz: 80,
      flashChipSize: 1048576
    };
  }

  generateTasks() {
    return [
      {
        name: "discovery_send",
        interval: 1000,
        enabled: true,
        running: true,
        autoStart: true
      },
      {
        name: "heartbeat", 
        interval: 2000,
        enabled: true,
        running: true,
        autoStart: true
      },
      {
        name: "status_update",
        interval: 1000,
        enabled: true,
        running: true,
        autoStart: true
      },
      {
        name: "wifi_monitor",
        interval: 5000,
        enabled: true,
        running: Math.random() > 0.1, // 90% chance of running
        autoStart: true
      },
      {
        name: "ota_check",
        interval: 30000,
        enabled: true,
        running: Math.random() > 0.2, // 80% chance of running
        autoStart: true
      },
      {
        name: "cluster_sync",
        interval: 10000,
        enabled: true,
        running: Math.random() > 0.05, // 95% chance of running
        autoStart: true
      }
    ];
  }

  generateApiEndpoints() {
    return [
      { uri: "/api/node/status", method: "GET" },
      { uri: "/api/tasks/status", method: "GET" },
      { uri: "/api/tasks/control", method: "POST" },
      { uri: "/api/cluster/members", method: "GET" },
      { uri: "/api/node/update", method: "POST" },
      { uri: "/api/node/restart", method: "POST" },
      { 
        uri: "/api/led/brightness", 
        method: "POST",
        params: [
          {
            name: "brightness",
            type: "numberRange",
            location: "body",
            required: true,
            value: 255,
            default: 128
          }
        ]
      },
      { 
        uri: "/api/led/color", 
        method: "POST",
        params: [
          {
            name: "color",
            type: "color",
            location: "body",
            required: true,
            default: 16711680
          }
        ]
      },
      { 
        uri: "/api/sensor/interval", 
        method: "POST",
        params: [
          {
            name: "interval",
            type: "numberRange",
            location: "body",
            required: true,
            value: 10000,
            default: 1000
          }
        ]
      },
      { 
        uri: "/api/system/mode", 
        method: "POST",
        params: [
          {
            name: "mode",
            type: "string",
            location: "body",
            required: true,
            values: ["normal", "debug", "maintenance"],
            default: "normal"
          }
        ]
      }
    ];
  }

  updateNodeStates() {
    if (!MOCK_CONFIG.simulation.enableTimeProgression) return;

    this.nodeStates.forEach((nodeState, ip) => {
      // Update uptime
      nodeState.uptime = Date.now() - this.startTime;
      
      // Update free heap (simulate memory usage changes)
      const currentHeap = nodeState.freeHeap;
      const change = Math.floor((Math.random() - 0.5) * 1000);
      nodeState.freeHeap = Math.max(10000, currentHeap + change);
      
      // Update last seen
      nodeState.lastSeen = Date.now();
      
      // Simulate random failures
      if (MOCK_CONFIG.simulation.enableRandomFailures && Math.random() < MOCK_CONFIG.simulation.failureRate) {
        nodeState.status = Math.random() > 0.5 ? 'INACTIVE' : 'DEAD';
      } else {
        nodeState.status = 'ACTIVE';
      }
      
      // Update task states
      nodeState.tasks.forEach(task => {
        if (task.enabled && Math.random() > 0.05) { // 95% chance of running when enabled
          task.running = true;
        } else {
          task.running = false;
        }
      });
    });

    // Rotate primary node if enabled
    if (MOCK_CONFIG.simulation.primaryNodeRotation) {
      this.primaryNodeIndex = (this.primaryNodeIndex + 1) % MOCK_CONFIG.nodes.length;
    }
  }

  getPrimaryNode() {
    return MOCK_CONFIG.nodes[this.primaryNodeIndex];
  }

  getAllNodes() {
    return Array.from(this.nodeStates.values());
  }

  getNodeByIp(ip) {
    return this.nodeStates.get(ip);
  }
}

// Initialize mock data generator
const mockData = new MockDataGenerator();

// Update data periodically
setInterval(() => {
  mockData.updateNodeStates();
}, MOCK_CONFIG.simulation.updateInterval);

// API Routes

// Health check endpoint
app.get('/api/health', (req, res) => {
  const primaryNode = mockData.getPrimaryNode();
  const allNodes = mockData.getAllNodes();
  const activeNodes = allNodes.filter(node => node.status === 'ACTIVE');
  
  const health = {
    status: activeNodes.length > 0 ? 'healthy' : 'degraded',
    timestamp: new Date().toISOString(),
    services: {
      http: true,
      udp: false, // Mock server doesn't use UDP
      sporeClient: true
    },
    discovery: {
      totalNodes: allNodes.length,
      primaryNode: primaryNode.ip,
      udpPort: 4210,
      serverRunning: false // Mock server doesn't use UDP
    },
    mock: {
      enabled: true,
      nodes: allNodes.length,
      activeNodes: activeNodes.length,
      simulationMode: MOCK_CONFIG.simulation.enableTimeProgression
    }
  };
  
  if (activeNodes.length === 0) {
    health.status = 'degraded';
    health.message = 'No active nodes in mock simulation';
  }
  
  res.json(health);
});

// Discovery endpoints (simulated)
app.get('/api/discovery/nodes', (req, res) => {
  const primaryNode = mockData.getPrimaryNode();
  const allNodes = mockData.getAllNodes();
  
  const response = {
    primaryNode: primaryNode.ip,
    totalNodes: allNodes.length,
    clientInitialized: true,
    clientBaseUrl: `http://${primaryNode.ip}`,
    nodes: allNodes.map(node => ({
      ip: node.ip,
      port: 80,
      discoveredAt: new Date(node.lastSeen - 60000).toISOString(), // 1 minute ago
      lastSeen: new Date(node.lastSeen).toISOString(),
      isPrimary: node.ip === primaryNode.ip,
      hostname: node.hostname,
      status: node.status
    }))
  };
  
  res.json(response);
});

app.post('/api/discovery/refresh', (req, res) => {
  // Simulate discovery refresh
  mockData.updateNodeStates();
  res.json({
    success: true,
    message: 'Discovery refresh completed',
    timestamp: new Date().toISOString()
  });
});

app.post('/api/discovery/primary/:ip', (req, res) => {
  const { ip } = req.params;
  const node = mockData.getNodeByIp(ip);
  
  if (!node) {
    return res.status(404).json({
      success: false,
      message: `Node ${ip} not found`
    });
  }
  
  // Find and set as primary
  const nodeIndex = MOCK_CONFIG.nodes.findIndex(n => n.ip === ip);
  if (nodeIndex !== -1) {
    mockData.primaryNodeIndex = nodeIndex;
  }
  
  res.json({
    success: true,
    message: `Primary node set to ${ip}`,
    primaryNode: ip
  });
});

app.post('/api/discovery/random-primary', (req, res) => {
  const allNodes = mockData.getAllNodes();
  const activeNodes = allNodes.filter(node => node.status === 'ACTIVE');
  
  if (activeNodes.length === 0) {
    return res.status(503).json({
      success: false,
      message: 'No active nodes available for selection'
    });
  }
  
  // Randomly select a new primary
  const randomIndex = Math.floor(Math.random() * activeNodes.length);
  const newPrimary = activeNodes[randomIndex];
  const nodeIndex = MOCK_CONFIG.nodes.findIndex(n => n.ip === newPrimary.ip);
  
  if (nodeIndex !== -1) {
    mockData.primaryNodeIndex = nodeIndex;
  }
  
  res.json({
    success: true,
    message: `Primary node randomly selected: ${newPrimary.ip}`,
    primaryNode: newPrimary.ip,
    totalNodes: allNodes.length,
    clientInitialized: true
  });
});

// Task management endpoints
app.get('/api/tasks/status', (req, res) => {
  const { ip } = req.query;
  let nodeData;
  
  if (ip) {
    nodeData = mockData.getNodeByIp(ip);
    if (!nodeData) {
      return res.status(404).json({
        error: 'Node not found',
        message: `Node ${ip} not found in mock simulation`
      });
    }
  } else {
    // Use primary node
    const primaryNode = mockData.getPrimaryNode();
    nodeData = mockData.getNodeByIp(primaryNode.ip);
  }
  
  const tasks = nodeData.tasks;
  const activeTasks = tasks.filter(task => task.enabled && task.running).length;
  
  const response = {
    summary: {
      totalTasks: tasks.length,
      activeTasks: activeTasks
    },
    tasks: tasks,
    system: {
      freeHeap: nodeData.freeHeap,
      uptime: nodeData.uptime
    }
  };
  
  res.json(response);
});

app.post('/api/tasks/control', (req, res) => {
  const { task, action } = req.body;
  
  if (!task || !action) {
    return res.status(400).json({
      success: false,
      message: 'Missing parameters. Required: task, action',
      example: '{"task": "discovery_send", "action": "status"}'
    });
  }
  
  const validActions = ['enable', 'disable', 'start', 'stop', 'status'];
  if (!validActions.includes(action)) {
    return res.status(400).json({
      success: false,
      message: 'Invalid action. Use: enable, disable, start, stop, or status',
      task: task,
      action: action
    });
  }
  
  // Simulate task control
  const primaryNode = mockData.getPrimaryNode();
  const nodeData = mockData.getNodeByIp(primaryNode.ip);
  const taskData = nodeData.tasks.find(t => t.name === task);
  
  if (!taskData) {
    return res.status(404).json({
      success: false,
      message: `Task ${task} not found`
    });
  }
  
  // Apply action
  switch (action) {
    case 'enable':
      taskData.enabled = true;
      break;
    case 'disable':
      taskData.enabled = false;
      taskData.running = false;
      break;
    case 'start':
      if (taskData.enabled) {
        taskData.running = true;
      }
      break;
    case 'stop':
      taskData.running = false;
      break;
    case 'status':
      // Return detailed status
      return res.json({
        success: true,
        message: 'Task status retrieved',
        task: task,
        action: action,
        taskDetails: {
          name: taskData.name,
          enabled: taskData.enabled,
          running: taskData.running,
          interval: taskData.interval,
          system: {
            freeHeap: nodeData.freeHeap,
            uptime: nodeData.uptime
          }
        }
      });
  }
  
  res.json({
    success: true,
    message: `Task ${action}d`,
    task: task,
    action: action
  });
});

// System status endpoint
app.get('/api/node/status', (req, res) => {
  const { ip } = req.query;
  let nodeData;
  
  if (ip) {
    nodeData = mockData.getNodeByIp(ip);
    if (!nodeData) {
      return res.status(404).json({
        error: 'Node not found',
        message: `Node ${ip} not found in mock simulation`
      });
    }
  } else {
    // Use primary node
    const primaryNode = mockData.getPrimaryNode();
    nodeData = mockData.getNodeByIp(primaryNode.ip);
  }
  
  const response = {
    freeHeap: nodeData.freeHeap,
    chipId: nodeData.chipId,
    sdkVersion: nodeData.systemInfo.sdkVersion,
    cpuFreqMHz: nodeData.systemInfo.cpuFreqMHz,
    flashChipSize: nodeData.systemInfo.flashChipSize,
    api: nodeData.apiEndpoints
  };
  
  res.json(response);
});

// Cluster members endpoint
app.get('/api/cluster/members', (req, res) => {
  const allNodes = mockData.getAllNodes();
  
  const members = allNodes.map(node => ({
    hostname: node.hostname,
    ip: node.ip,
    lastSeen: Math.floor(node.lastSeen / 1000), // Convert to seconds
    latency: node.latency,
    status: node.status,
    resources: {
      freeHeap: node.freeHeap,
      chipId: node.chipId,
      sdkVersion: node.systemInfo.sdkVersion,
      cpuFreqMHz: node.systemInfo.cpuFreqMHz,
      flashChipSize: node.systemInfo.flashChipSize
    },
    api: node.apiEndpoints
  }));
  
  res.json({ members });
});

// Node endpoints endpoint
app.get('/api/node/endpoints', (req, res) => {
  const { ip } = req.query;
  let nodeData;
  
  if (ip) {
    nodeData = mockData.getNodeByIp(ip);
    if (!nodeData) {
      return res.status(404).json({
        error: 'Node not found',
        message: `Node ${ip} not found in mock simulation`
      });
    }
  } else {
    // Use primary node
    const primaryNode = mockData.getPrimaryNode();
    nodeData = mockData.getNodeByIp(primaryNode.ip);
  }
  
  res.json(nodeData.apiEndpoints);
});

// Generic proxy endpoint
app.post('/api/proxy-call', (req, res) => {
  const { ip, method, uri, params } = req.body || {};
  
  if (!ip || !method || !uri) {
    return res.status(400).json({
      error: 'Missing required fields',
      message: 'Required: ip, method, uri'
    });
  }
  
  // Simulate proxy call by routing to appropriate mock endpoint
  const nodeData = mockData.getNodeByIp(ip);
  if (!nodeData) {
    return res.status(404).json({
      error: 'Node not found',
      message: `Node ${ip} not found in mock simulation`
    });
  }
  
  // Simulate different responses based on URI
  if (uri === '/api/node/status') {
    return res.json({
      freeHeap: nodeData.freeHeap,
      chipId: nodeData.chipId,
      sdkVersion: nodeData.systemInfo.sdkVersion,
      cpuFreqMHz: nodeData.systemInfo.cpuFreqMHz,
      flashChipSize: nodeData.systemInfo.flashChipSize,
      api: nodeData.apiEndpoints
    });
  } else if (uri === '/api/tasks/status') {
    const tasks = nodeData.tasks;
    const activeTasks = tasks.filter(task => task.enabled && task.running).length;
    
    return res.json({
      summary: {
        totalTasks: tasks.length,
        activeTasks: activeTasks
      },
      tasks: tasks,
      system: {
        freeHeap: nodeData.freeHeap,
        uptime: nodeData.uptime
      }
    });
  } else if (uri === '/api/monitoring/resources') {
    // Return realistic monitoring resources data
    const totalHeap = nodeData.systemInfo.flashChipSize || 1048576; // 1MB default
    const freeHeap = nodeData.freeHeap;
    const usedHeap = totalHeap - freeHeap;
    const heapUsagePercent = (usedHeap / totalHeap) * 100;
    
    return res.json({
      cpu: {
        average_usage: Math.random() * 30 + 10, // 10-40% CPU usage
        current_usage: Math.random() * 50 + 5,  // 5-55% current usage
        frequency_mhz: nodeData.systemInfo.cpuFreqMHz || 80
      },
      memory: {
        total_heap: totalHeap,
        free_heap: freeHeap,
        used_heap: usedHeap,
        heap_usage_percent: heapUsagePercent,
        min_free_heap: Math.floor(freeHeap * 0.8), // 80% of current free heap
        max_alloc_heap: Math.floor(totalHeap * 0.9) // 90% of total heap
      },
      filesystem: {
        total_bytes: 3145728, // 3MB SPIFFS
        used_bytes: Math.floor(3145728 * (0.3 + Math.random() * 0.4)), // 30-70% used
        free_bytes: 0 // Will be calculated
      },
      network: {
        wifi_rssi: -30 - Math.floor(Math.random() * 40), // -30 to -70 dBm
        wifi_connected: true,
        uptime_seconds: nodeData.uptime
      },
      timestamp: new Date().toISOString()
    });
  } else {
    return res.json({
      success: true,
      message: `Mock response for ${method} ${uri}`,
      node: ip,
      timestamp: new Date().toISOString()
    });
  }
});

// Firmware update endpoint
app.post('/api/node/update', (req, res) => {
  // Simulate firmware update
  res.json({
    status: 'updating',
    message: 'Firmware update in progress (mock simulation)'
  });
});

// System restart endpoint
app.post('/api/node/restart', (req, res) => {
  // Simulate system restart
  res.json({
    status: 'restarting'
  });
});

// Test route
app.get('/test', (req, res) => {
  res.send('Mock server is working!');
});

// Serve the mock UI (main UI with modified API client)
app.get('/', (req, res) => {
  const filePath = path.join(__dirname, 'mock-ui.html');
  console.log('Serving mock UI from:', filePath);
  res.sendFile(filePath);
});

// Serve the original mock frontend
app.get('/frontend', (req, res) => {
  res.sendFile(path.join(__dirname, 'mock-frontend.html'));
});

// Serve the main UI with modified API client
app.get('/ui', (req, res) => {
  res.sendFile(path.join(__dirname, '../public/index.html'));
});

// Serve static files from public directory (after custom routes)
// Only serve static files for specific paths, not the root
app.use('/static', express.static(path.join(__dirname, '../public')));
app.use('/styles', express.static(path.join(__dirname, '../public/styles')));
app.use('/scripts', express.static(path.join(__dirname, '../public/scripts')));
app.use('/vendor', express.static(path.join(__dirname, '../public/vendor')));

// Serve mock API client
app.get('/test/mock-api-client.js', (req, res) => {
  res.sendFile(path.join(__dirname, 'mock-api-client.js'));
});

// Serve test page
app.get('/test-page', (req, res) => {
  res.sendFile(path.join(__dirname, 'test-page.html'));
});

// Serve favicon to prevent 404 errors
app.get('/favicon.ico', (req, res) => {
  res.status(204).end(); // No content
});

// Serve mock server info page
app.get('/info', (req, res) => {
  res.send(`
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>SPORE UI - Mock Server Info</title>
        <style>
            body { font-family: Arial, sans-serif; margin: 40px; background: #f5f5f5; }
            .container { max-width: 800px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
            h1 { color: #333; text-align: center; }
            .status { background: #e8f5e8; padding: 15px; border-radius: 5px; margin: 20px 0; }
            .info { background: #f0f8ff; padding: 15px; border-radius: 5px; margin: 20px 0; }
            .endpoint { background: #f9f9f9; padding: 10px; margin: 5px 0; border-left: 4px solid #007acc; }
            .mock-note { background: #fff3cd; padding: 15px; border-radius: 5px; margin: 20px 0; border-left: 4px solid #ffc107; }
            .btn { display: inline-block; padding: 10px 20px; background: #007acc; color: white; text-decoration: none; border-radius: 5px; margin: 5px; }
            .btn:hover { background: #005a9e; }
        </style>
    </head>
    <body>
        <div class="container">
            <h1>🚀 SPORE UI Mock Server</h1>
            
            <div class="mock-note">
                <strong>Mock Mode Active:</strong> This is a complete simulation of the SPORE embedded system.
                No real hardware or UDP ports are required.
            </div>
            
            <div class="status">
                <h3>📊 Server Status</h3>
                <p><strong>Status:</strong> Running</p>
                <p><strong>Port:</strong> ${MOCK_CONFIG.port}</p>
                <p><strong>Configuration:</strong> ${MOCK_CONFIG.name}</p>
                <p><strong>Mock Nodes:</strong> ${MOCK_CONFIG.nodes.length}</p>
                <p><strong>Primary Node:</strong> ${mockData.getPrimaryNode().ip}</p>
            </div>
            
            <div class="info">
                <h3>🌐 Access Points</h3>
                <p><a href="/" class="btn">Mock UI (Port 3002)</a> - Full UI with mock data</p>
                <p><a href="/frontend" class="btn">Mock Frontend</a> - Custom mock frontend</p>
                <p><a href="/ui" class="btn">Real UI (Port 3002)</a> - Real UI connected to mock server</p>
                <p><a href="/api/health" class="btn">API Health</a> - Check server status</p>
            </div>
            
            <div class="info">
                <h3>🔗 Available Endpoints</h3>
                <div class="endpoint"><strong>GET</strong> /api/health - Health check</div>
                <div class="endpoint"><strong>GET</strong> /api/discovery/nodes - Discovery status</div>
                <div class="endpoint"><strong>GET</strong> /api/tasks/status - Task status</div>
                <div class="endpoint"><strong>POST</strong> /api/tasks/control - Control tasks</div>
                <div class="endpoint"><strong>GET</strong> /api/node/status - System status</div>
                <div class="endpoint"><strong>GET</strong> /api/cluster/members - Cluster members</div>
                <div class="endpoint"><strong>POST</strong> /api/proxy-call - Generic proxy</div>
            </div>
            
            <div class="info">
                <h3>🎮 Mock Features</h3>
                <ul>
                    <li>✅ Multiple simulated SPORE nodes</li>
                    <li>✅ Realistic data that changes over time</li>
                    <li>✅ No UDP port conflicts</li>
                    <li>✅ All API endpoints implemented</li>
                    <li>✅ Random failures simulation</li>
                    <li>✅ Primary node rotation</li>
                </ul>
            </div>
            
            <div class="info">
                <h3>🔧 Configuration</h3>
                <p>Use npm scripts to change configuration:</p>
                <ul>
                    <li><code>npm run mock:healthy</code> - Healthy cluster (3 nodes)</li>
                    <li><code>npm run mock:degraded</code> - Degraded cluster (some inactive)</li>
                    <li><code>npm run mock:large</code> - Large cluster (8 nodes)</li>
                    <li><code>npm run mock:unstable</code> - Unstable cluster (high failure rate)</li>
                    <li><code>npm run mock:single</code> - Single node</li>
                    <li><code>npm run mock:empty</code> - Empty cluster</li>
                </ul>
            </div>
        </div>
    </body>
    </html>
  `);
});

// Start the mock server
const server = app.listen(MOCK_CONFIG.port, () => {
  console.log('🚀 SPORE UI Mock Server Started');
  console.log('================================');
  console.log(`Configuration: ${MOCK_CONFIG.name}`);
  console.log(`Description: ${MOCK_CONFIG.description}`);
  console.log(`Port: ${MOCK_CONFIG.port}`);
  console.log(`URL: http://localhost:${MOCK_CONFIG.port}`);
  console.log(`Mock Nodes: ${MOCK_CONFIG.nodes.length}`);
  console.log(`Primary Node: ${mockData.getPrimaryNode().ip}`);
  console.log('');
  console.log('📡 Available Mock Nodes:');
  MOCK_CONFIG.nodes.forEach((node, index) => {
    console.log(`  ${index + 1}. ${node.hostname} (${node.ip}) - ${node.status}`);
  });
  console.log('');
  console.log('🎮 Mock Features:');
  console.log('  ✅ No UDP port conflicts');
  console.log('  ✅ Realistic data simulation');
  console.log('  ✅ All API endpoints');
  console.log(`  ✅ Time-based data updates (${MOCK_CONFIG.simulation.updateInterval}ms)`);
  console.log(`  ✅ Random failure simulation (${MOCK_CONFIG.simulation.enableRandomFailures ? 'Enabled' : 'Disabled'})`);
  console.log(`  ✅ Primary node rotation (${MOCK_CONFIG.simulation.primaryNodeRotation ? 'Enabled' : 'Disabled'})`);
  console.log('');
  console.log('Press Ctrl+C to stop');
});

// Graceful shutdown
process.on('SIGINT', () => {
  console.log('\n\n👋 Mock server stopped. Goodbye!');
  server.close(() => {
    process.exit(0);
  });
});

module.exports = { app, mockData, MOCK_CONFIG };
