/**
 * Voice Command Routing Test
 * Tests that voice commands from LiveKit agents are routed to the correct Chrome extension
 */

import WebSocket from 'ws';
import fetch from 'node-fetch';

const CHROME_WS_URL = 'ws://localhost:3001/chrome';
const MCP_HTTP_URL = 'http://localhost:3001/mcp';

class MockChromeExtension {
  constructor(userId) {
    this.userId = userId;
    this.chromeUserId = `user_${Date.now()}_${userId}_${Math.random().toString(36).substring(2, 8)}`;
    this.ws = null;
    this.sessionInfo = null;
    this.receivedCommands = [];
  }

  async connect() {
    return new Promise((resolve, reject) => {
      console.log(`🔌 [Chrome ${this.userId}] Connecting with user ID: ${this.chromeUserId}`);
      
      this.ws = new WebSocket(CHROME_WS_URL);

      this.ws.on('open', () => {
        // Send connection info with user ID
        const connectionInfo = {
          type: 'connection_info',
          userId: this.chromeUserId,
          userAgent: `MockChrome-${this.userId}`,
          timestamp: Date.now(),
          extensionId: `mock-extension-${this.userId}`
        };

        this.ws.send(JSON.stringify(connectionInfo));
      });

      this.ws.on('message', (data) => {
        try {
          const message = JSON.parse(data.toString());
          
          if (message.type === 'session_info') {
            this.sessionInfo = message.sessionInfo;
            console.log(`✅ [Chrome ${this.userId}] Session established: ${this.sessionInfo.sessionId}`);
            resolve();
          }

          // Handle tool calls (voice commands)
          if (message.action === 'callTool') {
            this.receivedCommands.push(message);
            console.log(`🎤 [Chrome ${this.userId}] Received voice command: ${message.params.name}`);
            
            // Send response
            const response = {
              id: message.id,
              success: true,
              result: `Command executed by Chrome ${this.userId}`,
              timestamp: Date.now()
            };
            
            this.ws.send(JSON.stringify(response));
          }

        } catch (error) {
          console.error(`❌ [Chrome ${this.userId}] Error parsing message:`, error);
        }
      });

      this.ws.on('error', reject);

      setTimeout(() => {
        if (!this.sessionInfo) {
          reject(new Error(`Timeout waiting for session info for Chrome ${this.userId}`));
        }
      }, 5000);
    });
  }

  disconnect() {
    if (this.ws) {
      this.ws.close();
    }
  }
}

class MockLiveKitAgent {
  constructor(userId) {
    this.userId = userId;
    this.chromeUserId = userId; // This should match the Chrome extension's user ID
  }

  async sendVoiceCommand(toolName, args) {
    console.log(`🎙️ [LiveKit ${this.userId}] Sending voice command: ${toolName}`);
    
    const payload = {
      jsonrpc: '2.0',
      id: Date.now(),
      method: 'tools/call',
      params: {
        name: toolName,
        arguments: args
      }
    };

    const headers = {
      'Content-Type': 'application/json',
      'chrome-user-id': this.chromeUserId // Route to specific Chrome extension
    };

    try {
      const response = await fetch(MCP_HTTP_URL, {
        method: 'POST',
        headers: headers,
        body: JSON.stringify(payload)
      });

      const result = await response.json();
      console.log(`📨 [LiveKit ${this.userId}] Voice command response:`, result);
      return result;
    } catch (error) {
      console.error(`❌ [LiveKit ${this.userId}] Error sending voice command:`, error);
      throw error;
    }
  }
}

async function testVoiceCommandRouting() {
  console.log('🎤 Starting Voice Command Routing Test...\n');

  const chromeExtensions = [];
  const liveKitAgents = [];

  try {
    // Step 1: Create and connect Chrome extensions
    console.log('📋 STEP 1: Setting up Chrome Extensions');
    console.log('=' .repeat(50));

    for (let i = 1; i <= 2; i++) {
      const chrome = new MockChromeExtension(i);
      chromeExtensions.push(chrome);
      
      await chrome.connect();
      console.log(`✅ Chrome ${i} connected with user ID: ${chrome.chromeUserId}`);
      
      // Create corresponding LiveKit agent
      const agent = new MockLiveKitAgent(chrome.chromeUserId);
      liveKitAgents.push(agent);
      
      await new Promise(resolve => setTimeout(resolve, 1000));
    }

    // Step 2: Test voice command routing
    console.log('\n📋 STEP 2: Testing Voice Command Routing');
    console.log('=' .repeat(50));

    // Send commands from each LiveKit agent
    for (let i = 0; i < liveKitAgents.length; i++) {
      const agent = liveKitAgents[i];
      const chrome = chromeExtensions[i];
      
      console.log(`\n🎙️ Testing voice command from LiveKit Agent ${i + 1} to Chrome ${i + 1}`);
      
      await agent.sendVoiceCommand('chrome_navigate', {
        url: `https://example.com/user${i + 1}`,
        userContext: agent.chromeUserId
      });
      
      // Wait for command to be processed
      await new Promise(resolve => setTimeout(resolve, 2000));
    }

    // Step 3: Test cross-user isolation
    console.log('\n📋 STEP 3: Testing Cross-User Isolation');
    console.log('=' .repeat(50));

    // Agent 1 sends command that should only go to Chrome 1
    console.log('\n🔒 Testing isolation: Agent 1 → Chrome 1 only');
    await liveKitAgents[0].sendVoiceCommand('chrome_click_element', {
      selector: '#test-button',
      userContext: liveKitAgents[0].chromeUserId
    });

    await new Promise(resolve => setTimeout(resolve, 2000));

    // Step 4: Verify results
    console.log('\n📋 STEP 4: Verifying Results');
    console.log('=' .repeat(50));

    chromeExtensions.forEach((chrome, index) => {
      console.log(`\n👤 Chrome Extension ${index + 1} (${chrome.chromeUserId}):`);
      console.log(`   Session ID: ${chrome.sessionInfo?.sessionId}`);
      console.log(`   Commands Received: ${chrome.receivedCommands.length}`);
      
      chrome.receivedCommands.forEach((cmd, cmdIndex) => {
        console.log(`   Command ${cmdIndex + 1}: ${cmd.params.name}`);
      });
    });

    // Verify isolation
    const totalCommands = chromeExtensions.reduce((sum, chrome) => sum + chrome.receivedCommands.length, 0);
    const expectedCommands = liveKitAgents.length * 2; // 2 commands per agent

    console.log(`\n📊 RESULTS:`);
    console.log(`   Total Commands Sent: ${expectedCommands}`);
    console.log(`   Total Commands Received: ${totalCommands}`);
    console.log(`   Routing Success: ${totalCommands === expectedCommands ? '✅' : '❌'}`);
    
    // Check that each Chrome extension received the right number of commands
    const isolationSuccess = chromeExtensions.every(chrome => chrome.receivedCommands.length === 2);
    console.log(`   User Isolation: ${isolationSuccess ? '✅' : '❌'}`);

    if (totalCommands === expectedCommands && isolationSuccess) {
      console.log('\n🎉 Voice Command Routing Test PASSED!');
    } else {
      console.log('\n❌ Voice Command Routing Test FAILED!');
    }

  } catch (error) {
    console.error('❌ Test failed:', error);
  } finally {
    // Cleanup
    console.log('\n🧹 Cleaning up...');
    chromeExtensions.forEach(chrome => chrome.disconnect());
    
    setTimeout(() => {
      console.log('✅ Test completed');
      process.exit(0);
    }, 2000);
  }
}

// Run the test
testVoiceCommandRouting().catch(console.error);
