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

let testServer: ITestServer;

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

tap.test('CSEC-03: Basic DKIM signature structure', async () => {
  const smtpClient = createTestSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Create email with DKIM configuration
  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    subject: 'DKIM Signed Email',
    text: 'This email should be DKIM signed'
  });

  // Note: DKIM signing would be handled by the Email class or SMTP client
  // This test verifies the structure when it's implemented
  const result = await smtpClient.sendMail(email);
  expect(result.success).toBeTruthy();
  
  console.log('Email sent successfully');
  console.log('Note: DKIM signing functionality would be applied here');

  await smtpClient.close();
});

tap.test('CSEC-03: DKIM with RSA key generation', async () => {
  // Generate a test RSA key pair
  const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: {
      type: 'spki',
      format: 'pem'
    },
    privateKeyEncoding: {
      type: 'pkcs8',
      format: 'pem'
    }
  });

  console.log('Generated RSA key pair for DKIM:');
  console.log('Public key (first line):', publicKey.split('\n')[1].substring(0, 50) + '...');
  
  // Create DNS TXT record format
  const publicKeyBase64 = publicKey
    .replace(/-----BEGIN PUBLIC KEY-----/, '')
    .replace(/-----END PUBLIC KEY-----/, '')
    .replace(/\s/g, '');
  
  console.log('\nDNS TXT record for default._domainkey.example.com:');
  console.log(`v=DKIM1; k=rsa; p=${publicKeyBase64.substring(0, 50)}...`);

  const smtpClient = createTestSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  const email = new Email({
    from: 'sender@example.com',
    to: ['recipient@example.com'],
    subject: 'DKIM with Real RSA Key',
    text: 'This email is signed with a real RSA key'
  });

  const result = await smtpClient.sendMail(email);
  expect(result.success).toBeTruthy();

  await smtpClient.close();
});

tap.test('CSEC-03: DKIM body hash calculation', async () => {
  const smtpClient = createTestSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: false
  });

  // Test body hash with different content
  const testBodies = [
    { name: 'Simple text', body: 'Hello World' },
    { name: 'Multi-line text', body: 'Line 1\r\nLine 2\r\nLine 3' },
    { name: 'Empty body', body: '' }
  ];

  for (const test of testBodies) {
    console.log(`\nTesting body hash for: ${test.name}`);
    
    // Calculate expected body hash
    const canonicalBody = test.body.replace(/\r\n/g, '\n').trimEnd() + '\n';
    const bodyHash = crypto.createHash('sha256').update(canonicalBody).digest('base64');
    console.log(`  Expected hash: ${bodyHash.substring(0, 20)}...`);
    
    const email = new Email({
      from: 'sender@example.com',
      to: ['recipient@example.com'],
      subject: `Body Hash Test: ${test.name}`,
      text: test.body
    });

    const result = await smtpClient.sendMail(email);
    expect(result.success).toBeTruthy();
  }

  await smtpClient.close();
});

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

tap.start();