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 dns from 'dns';
import { promisify } from 'util';

const resolveTxt = promisify(dns.resolveTxt);

let testServer: ITestServer;

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

tap.test('CSEC-04: SPF record parsing', async () => {
  // Test SPF record parsing
  const testSpfRecords = [
    {
      domain: 'example.com',
      record: 'v=spf1 ip4:192.168.1.0/24 ip6:2001:db8::/32 include:_spf.google.com ~all',
      description: 'Standard SPF with IP ranges and include'
    },
    {
      domain: 'strict.com',
      record: 'v=spf1 mx a -all',
      description: 'Strict SPF with MX and A records'
    },
    {
      domain: 'softfail.com',
      record: 'v=spf1 ip4:10.0.0.1 ~all',
      description: 'Soft fail SPF'
    }
  ];

  console.log('SPF Record Analysis:\n');
  
  for (const test of testSpfRecords) {
    console.log(`Domain: ${test.domain}`);
    console.log(`Record: ${test.record}`);
    console.log(`Description: ${test.description}`);
    
    // Parse SPF mechanisms
    const mechanisms = test.record.match(/(\+|-|~|\?)?(\w+)(:[^\s]+)?/g);
    if (mechanisms) {
      console.log('Mechanisms found:', mechanisms.length);
    }
    console.log('');
  }
});

tap.test('CSEC-04: SPF alignment check', async () => {
  const smtpClient = createTestSmtpClient({
    host: testServer.hostname,
    port: testServer.port,
    secure: false,
    connectionTimeout: 5000,
    debug: true
  });

  // Test SPF alignment scenarios
  const alignmentTests = [
    {
      name: 'Aligned',
      from: 'sender@example.com',
      expectedAlignment: true
    },
    {
      name: 'Different domain',
      from: 'sender@otherdomain.com',
      expectedAlignment: false
    }
  ];

  for (const test of alignmentTests) {
    console.log(`\nTesting SPF alignment: ${test.name}`);
    console.log(`  From: ${test.from}`);
    
    const email = new Email({
      from: test.from,
      to: ['recipient@example.com'],
      subject: `SPF Alignment Test: ${test.name}`,
      text: 'Testing SPF alignment'
    });

    const result = await smtpClient.sendMail(email);
    expect(result.success).toBeTruthy();
    
    console.log(`  Email sent successfully`);
  }

  await smtpClient.close();
});

tap.test('CSEC-04: SPF lookup simulation', async () => {
  // Simulate SPF record lookups
  const testDomains = ['gmail.com'];
  
  console.log('\nSPF Record Lookups:\n');
  
  for (const domain of testDomains) {
    console.log(`Domain: ${domain}`);
    
    try {
      const txtRecords = await resolveTxt(domain);
      const spfRecords = txtRecords
        .map(record => record.join(''))
        .filter(record => record.startsWith('v=spf1'));
      
      if (spfRecords.length > 0) {
        console.log(`SPF Record found: ${spfRecords[0].substring(0, 50)}...`);
        
        // Count mechanisms
        const includes = (spfRecords[0].match(/include:/g) || []).length;
        console.log(`  Include count: ${includes}`);
      } else {
        console.log('  No SPF record found');
      }
    } catch (error) {
      console.log(`  Lookup failed: ${error.message}`);
    }
    console.log('');
  }
});

tap.test('CSEC-04: SPF best practices', async () => {
  // Test SPF best practices
  const bestPractices = [
    {
      practice: 'Use -all instead of ~all',
      good: 'v=spf1 include:_spf.example.com -all',
      bad: 'v=spf1 include:_spf.example.com ~all'
    },
    {
      practice: 'Avoid +all',
      good: 'v=spf1 ip4:192.168.1.0/24 -all',
      bad: 'v=spf1 +all'
    }
  ];

  console.log('\nSPF Best Practices:\n');
  
  for (const bp of bestPractices) {
    console.log(`${bp.practice}:`);
    console.log(`  ✓ Good: ${bp.good}`);
    console.log(`  ✗ Bad:  ${bp.bad}`);
    console.log('');
  }
});

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

tap.start();