import { tap, expect } from '@git.zone/tstest/tapbundle';
import { startTestServer, stopTestServer, type ITestServer } from '../../helpers/server.loader.js';
// import { createTestSmtpClient, sendConcurrentEmails, measureClientThroughput } from '../../helpers/smtp.client.js';
import { connectToSmtp, sendSmtpCommand, waitForGreeting, createMimeMessage, closeSmtpConnection } from '../../helpers/utils.js';

let testServer: ITestServer;

tap.test('setup - start SMTP server for performance testing', async () => {
  testServer = await startTestServer({
    port: 2531,
    hostname: 'localhost',
    maxConnections: 1000,
    size: 50 * 1024 * 1024 // 50MB for performance testing
  });
  expect(testServer).toBeInstanceOf(Object);
});

// TODO: Enable these tests when the helper functions are implemented
/*
tap.test('PERF-01: Throughput Testing - measure emails per second', async () => {
  const client = createTestSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    maxConnections: 10
  });
  
  try {
    // Warm up the connection pool
    console.log('🔥 Warming up connection pool...');
    await sendConcurrentEmails(client, 5);
    
    // Measure throughput for 10 seconds
    console.log('📊 Measuring throughput for 10 seconds...');
    const startTime = Date.now();
    const testDuration = 10000; // 10 seconds
    
    const result = await measureClientThroughput(client, testDuration, {
      from: 'perf-test@example.com',
      to: 'recipient@example.com',
      subject: 'Performance Test Email',
      text: 'This is a performance test email to measure throughput.'
    });
    
    const actualDuration = (Date.now() - startTime) / 1000;
    
    console.log('📈 Throughput Test Results:');
    console.log(`   Total emails sent: ${result.totalSent}`);
    console.log(`   Successful: ${result.successCount}`);
    console.log(`   Failed: ${result.errorCount}`);
    console.log(`   Duration: ${actualDuration.toFixed(2)}s`);
    console.log(`   Throughput: ${result.throughput.toFixed(2)} emails/second`);
    
    // Performance expectations
    expect(result.throughput).toBeGreaterThan(10); // At least 10 emails/second
    expect(result.errorCount).toBeLessThan(result.totalSent * 0.05); // Less than 5% errors
    
    console.log('✅ Throughput test passed');
    
  } finally {
    if (client.close) {
      await client.close();
    }
  }
});

tap.test('PERF-01: Burst throughput - handle sudden load spikes', async () => {
  const client = createTestSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    maxConnections: 20
  });
  
  try {
    // Send burst of emails
    const burstSize = 100;
    console.log(`💥 Sending burst of ${burstSize} emails...`);
    
    const startTime = Date.now();
    const results = await sendConcurrentEmails(client, burstSize, {
      from: 'burst-test@example.com',
      to: 'recipient@example.com',
      subject: 'Burst Test Email',
      text: 'Testing burst performance.'
    });
    
    const duration = Date.now() - startTime;
    const successCount = results.filter(r => r && !r.rejected).length;
    const throughput = (successCount / duration) * 1000;
    
    console.log(`✅ Burst completed in ${duration}ms`);
    console.log(`   Success rate: ${successCount}/${burstSize} (${(successCount/burstSize*100).toFixed(1)}%)`);
    console.log(`   Burst throughput: ${throughput.toFixed(2)} emails/second`);
    
    expect(successCount).toBeGreaterThan(burstSize * 0.95); // 95% success rate
    
  } finally {
    if (client.close) {
      await client.close();
    }
  }
});
*/

tap.test('PERF-01: Large message throughput - measure with varying sizes', async () => {
  const messageSizes = [
    { size: 1024, label: '1KB' },
    { size: 100 * 1024, label: '100KB' },
    { size: 1024 * 1024, label: '1MB' },
    { size: 5 * 1024 * 1024, label: '5MB' }
  ];
  
  for (const { size, label } of messageSizes) {
    console.log(`\n📧 Testing throughput with ${label} messages...`);
    
    const socket = await connectToSmtp(testServer.hostname, testServer.port);
    
    try {
      await waitForGreeting(socket);
      await sendSmtpCommand(socket, 'EHLO test.example.com', '250');
      
      // Send a few messages of this size
      const messageCount = 5;
      const timings: number[] = [];
      
      for (let i = 0; i < messageCount; i++) {
        const startTime = Date.now();
        
        await sendSmtpCommand(socket, 'MAIL FROM:<size-test@example.com>', '250');
        await sendSmtpCommand(socket, 'RCPT TO:<recipient@example.com>', '250');
        await sendSmtpCommand(socket, 'DATA', '354');
        
        // Create message with padding to reach target size
        const padding = 'X'.repeat(Math.max(0, size - 200)); // Account for headers
        const emailContent = createMimeMessage({
          from: 'size-test@example.com',
          to: 'recipient@example.com',
          subject: `${label} Performance Test`,
          text: padding
        });
        
        socket.write(emailContent);
        socket.write('\r\n.\r\n');
        
        // Wait for acceptance
        await new Promise<void>((resolve, reject) => {
          const timeout = setTimeout(() => reject(new Error('Timeout')), 30000);
          const onData = (data: Buffer) => {
            if (data.toString().includes('250')) {
              clearTimeout(timeout);
              socket.removeListener('data', onData);
              resolve();
            }
          };
          socket.on('data', onData);
        });
        
        const duration = Date.now() - startTime;
        timings.push(duration);
        
        // Reset for next message
        await sendSmtpCommand(socket, 'RSET', '250');
      }
      
      const avgTime = timings.reduce((a, b) => a + b, 0) / timings.length;
      const throughputMBps = (size / 1024 / 1024) / (avgTime / 1000);
      
      console.log(`   Average time: ${avgTime.toFixed(0)}ms`);
      console.log(`   Throughput: ${throughputMBps.toFixed(2)} MB/s`);
      
    } finally {
      await closeSmtpConnection(socket);
    }
  }
  
  console.log('\n✅ Large message throughput test completed');
});

tap.test('cleanup - stop SMTP server', async () => {
  await stopTestServer(testServer);
  console.log('✅ Test server stopped');
});

export default tap.start();