import { tap, expect } from '@git.zone/tstest/tapbundle';
import { startTestServer, stopTestServer, type ITestServer } from '../../helpers/server.loader.js';
import { createSmtpClient } from '../../../ts/mail/delivery/smtpclient/index.js';
import { Email } from '../../../ts/mail/core/classes.email.js';

let testServer: ITestServer;

tap.test('setup test SMTP server', async () => {
  testServer = await startTestServer({
    port: 2575,
    tlsEnabled: false,
    authRequired: false
  });
  expect(testServer).toBeTruthy();
  expect(testServer.port).toEqual(2575);
});

tap.test('CEDGE-06: Very long subject lines', async () => {
  console.log('Testing very long subject lines');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Test various subject line lengths
  const testSubjects = [
    'Normal Subject Line',
    'A'.repeat(100), // 100 chars
    'B'.repeat(500), // 500 chars  
    'C'.repeat(1000), // 1000 chars
    'D'.repeat(2000), // 2000 chars - very long
  ];

  for (const subject of testSubjects) {
    console.log(`  Testing subject length: ${subject.length} chars`);
    
    const email = new Email({
      from: 'sender@example.com',
      to: ['recipient@example.com'],
      subject: subject,
      text: 'Testing large subject headers'
    });

    const result = await smtpClient.sendMail(email);
    expect(result).toBeDefined();
    expect(result.messageId).toBeDefined();
  }

  await smtpClient.close();
});

tap.test('CEDGE-06: Multiple large headers', async () => {
  console.log('Testing multiple large headers');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Create email with multiple large headers
  const largeValue = 'X'.repeat(500);
  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    subject: 'Multiple large headers test',
    text: 'Testing multiple large headers',
    headers: {
      'X-Large-Header-1': largeValue,
      'X-Large-Header-2': largeValue,
      'X-Large-Header-3': largeValue,
      'X-Large-Header-4': largeValue,
      'X-Large-Header-5': largeValue,
      'X-Very-Long-Header-Name-That-Exceeds-Normal-Limits': 'Value for long header name',
      'X-Mixed-Content': `Start-${largeValue}-Middle-${largeValue}-End`
    }
  });

  const result = await smtpClient.sendMail(email);
  console.log(`Result: ${result.messageId ? 'Success' : 'Failed'}`);
  expect(result).toBeDefined();
  expect(result.messageId).toBeDefined();

  await smtpClient.close();
});

tap.test('CEDGE-06: Header folding and wrapping', async () => {
  console.log('Testing header folding and wrapping');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Create headers that should be folded
  const longHeaderValue = 'This is a very long header value that should exceed the recommended 78 character line limit and force the header to be folded across multiple lines according to RFC 5322 specifications';
  
  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    subject: 'Header folding test with a very long subject line that should also be folded properly',
    text: 'Testing header folding',
    headers: {
      'X-Long-Header': longHeaderValue,
      'X-Multi-Line': `Line 1 ${longHeaderValue}\nLine 2 ${longHeaderValue}\nLine 3 ${longHeaderValue}`,
      'X-Special-Chars': `Header with special chars: \t\r\n\x20 and unicode: 🎉 émojis`
    }
  });

  const result = await smtpClient.sendMail(email);
  console.log(`Result: ${result.messageId ? 'Success' : 'Failed'}`);
  expect(result).toBeDefined();
  expect(result.messageId).toBeDefined();

  await smtpClient.close();
});

tap.test('CEDGE-06: Maximum header size limits', async () => {
  console.log('Testing maximum header size limits');
  
  const smtpClient = createSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Test near RFC limits (recommended 998 chars per line)
  const nearMaxValue = 'Y'.repeat(900); // Near but under limit
  const overMaxValue = 'Z'.repeat(1500); // Over recommended limit
  
  const testCases = [
    { name: 'Near limit', value: nearMaxValue },
    { name: 'Over limit', value: overMaxValue }
  ];

  for (const testCase of testCases) {
    console.log(`  Testing ${testCase.name}: ${testCase.value.length} chars`);
    
    const email = new Email({
      from: 'sender@example.com',
      to: ['recipient@example.com'],
      subject: `Header size test: ${testCase.name}`,
      text: 'Testing header size limits',
      headers: {
        'X-Size-Test': testCase.value
      }
    });

    try {
      const result = await smtpClient.sendMail(email);
      console.log(`    ${testCase.name}: Success`);
      expect(result).toBeDefined();
    } catch (error) {
      console.log(`    ${testCase.name}: Failed (${error.message})`);
      // Some failures might be expected for oversized headers
      expect(error).toBeDefined();
    }
  }

  await smtpClient.close();
});

tap.test('cleanup test SMTP server', async () => {
  if (testServer) {
    await stopTestServer(testServer);
  }
});

export default tap.start();