import { tap, expect } from '@git.zone/tstest/tapbundle';
import { startTestServer, stopTestServer, type ITestServer, createTestServer as createSimpleTestServer } from '../../helpers/server.loader.js';
import { createTestSmtpClient } from '../../helpers/smtp.client.js';
import { Email } from '../../../ts/mail/core/classes.email.js';

let testServer: ITestServer;

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

tap.test('CSEC-06: Valid certificate acceptance', async () => {
  const smtpClient = createTestSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: true,
    tls: {
      rejectUnauthorized: false  // Accept self-signed for test
    }
  });

  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    subject: 'Valid certificate test',
    text: 'Testing with valid TLS connection'
  });

  const result = await smtpClient.sendMail(email);
  console.log(`Result: ${result.success ? 'Success' : 'Failed'}`);
  console.log('Certificate accepted for secure connection');
  expect(result.success).toBeTruthy();

  await smtpClient.close();
});

tap.test('CSEC-06: Self-signed certificate handling', async () => {
  // Test with strict validation (should fail)
  const strictClient = createTestSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: true,
    tls: {
      rejectUnauthorized: true  // Reject self-signed
    }
  });

  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    subject: 'Self-signed cert test',
    text: 'Testing self-signed certificate rejection'
  });

  try {
    await strictClient.sendMail(email);
    console.log('Unexpected: Self-signed cert was accepted');
  } catch (error) {
    console.log(`Expected error: ${error.message}`);
    expect(error.message).toInclude('self');
  }

  await strictClient.close();

  // Test with relaxed validation (should succeed)
  const relaxedClient = createTestSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: true,
    tls: {
      rejectUnauthorized: false  // Accept self-signed
    }
  });

  const result = await relaxedClient.sendMail(email);
  console.log('Self-signed cert accepted with relaxed validation');
  expect(result.success).toBeTruthy();

  await relaxedClient.close();
});

tap.test('CSEC-06: Certificate hostname verification', async () => {
  const smtpClient = createTestSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: true,
    tls: {
      rejectUnauthorized: false,  // For self-signed
      servername: testServer.hostname  // Verify hostname
    }
  });

  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    subject: 'Hostname verification test',
    text: 'Testing certificate hostname matching'
  });

  const result = await smtpClient.sendMail(email);
  console.log('Hostname verification completed');
  expect(result.success).toBeTruthy();

  await smtpClient.close();
});

tap.test('CSEC-06: Certificate validation with custom CA', async () => {
  const smtpClient = createTestSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: true,
    tls: {
      rejectUnauthorized: false,
      // In production, would specify CA certificates
      ca: undefined
    }
  });

  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    subject: 'Certificate chain test',
    text: 'Testing certificate chain validation'
  });

  const result = await smtpClient.sendMail(email);
  console.log('Certificate chain validation completed');
  expect(result.success).toBeTruthy();

  await smtpClient.close();
});

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

tap.start();