import * as plugins from '../../plugins.js';
import { logger } from '../../logger.js';
import { LRUCache } from 'lru-cache';
/**
 * Advanced email validator class using smartmail's capabilities
 */
export class EmailValidator {
    validator;
    dnsCache;
    constructor(options) {
        this.validator = new plugins.smartmail.EmailAddressValidator();
        // Initialize LRU cache for DNS records
        this.dnsCache = new LRUCache({
            // Default to 1000 entries (reasonable for most applications)
            max: options?.maxCacheSize || 1000,
            // Default TTL of 1 hour (DNS records don't change frequently)
            ttl: options?.cacheTTL || 60 * 60 * 1000,
            // Optional cache monitoring
            allowStale: false,
            updateAgeOnGet: true,
            // Add logging for cache events in production environments
            disposeAfter: (value, key) => {
                logger.log('debug', `DNS cache entry expired for domain: ${key}`);
            },
        });
    }
    /**
     * Validates an email address using comprehensive checks
     * @param email The email to validate
     * @param options Validation options
     * @returns Validation result with details
     */
    async validate(email, options = {}) {
        try {
            const result = {
                isValid: false,
                hasMx: false,
                hasSpamMarkings: false,
                score: 0,
                details: {
                    formatValid: false,
                    spamIndicators: []
                }
            };
            // Always check basic format
            result.details.formatValid = this.validator.isValidEmailFormat(email);
            if (!result.details.formatValid) {
                result.details.errorMessage = 'Invalid email format';
                return result;
            }
            // If syntax-only check is requested, return early
            if (options.checkSyntaxOnly) {
                result.isValid = true;
                result.score = 0.5;
                return result;
            }
            // Get domain for additional checks
            const domain = email.split('@')[1];
            // Check MX records
            if (options.checkMx !== false) {
                try {
                    const mxRecords = await this.getMxRecords(domain);
                    result.details.mxRecords = mxRecords;
                    result.hasMx = mxRecords && mxRecords.length > 0;
                    if (!result.hasMx) {
                        result.details.spamIndicators.push('No MX records');
                        result.details.errorMessage = 'Domain has no MX records';
                    }
                }
                catch (error) {
                    logger.log('error', `Error checking MX records: ${error.message}`);
                    result.details.errorMessage = 'Unable to check MX records';
                }
            }
            // Check if domain is disposable
            if (options.checkDisposable !== false) {
                result.details.disposable = await this.validator.isDisposableEmail(email);
                if (result.details.disposable) {
                    result.details.spamIndicators.push('Disposable email');
                }
            }
            // Check if email is a role account
            if (options.checkRole !== false) {
                result.details.role = this.validator.isRoleAccount(email);
                if (result.details.role) {
                    result.details.spamIndicators.push('Role account');
                }
            }
            // Calculate spam score and final validity
            result.hasSpamMarkings = result.details.spamIndicators.length > 0;
            // Calculate a score between 0-1 based on checks
            let scoreFactors = 0;
            let scoreTotal = 0;
            // Format check (highest weight)
            scoreFactors += 0.4;
            if (result.details.formatValid)
                scoreTotal += 0.4;
            // MX check (high weight)
            if (options.checkMx !== false) {
                scoreFactors += 0.3;
                if (result.hasMx)
                    scoreTotal += 0.3;
            }
            // Disposable check (medium weight)
            if (options.checkDisposable !== false) {
                scoreFactors += 0.2;
                if (!result.details.disposable)
                    scoreTotal += 0.2;
            }
            // Role account check (low weight)
            if (options.checkRole !== false) {
                scoreFactors += 0.1;
                if (!result.details.role)
                    scoreTotal += 0.1;
            }
            // Normalize score based on factors actually checked
            result.score = scoreFactors > 0 ? scoreTotal / scoreFactors : 0;
            // Email is valid if score is above 0.7 (configurable threshold)
            result.isValid = result.score >= 0.7;
            return result;
        }
        catch (error) {
            logger.log('error', `Email validation error: ${error.message}`);
            return {
                isValid: false,
                hasMx: false,
                hasSpamMarkings: true,
                score: 0,
                details: {
                    formatValid: false,
                    errorMessage: `Validation error: ${error.message}`,
                    spamIndicators: ['Validation error']
                }
            };
        }
    }
    /**
     * Gets MX records for a domain with caching
     * @param domain Domain to check
     * @returns Array of MX records
     */
    async getMxRecords(domain) {
        // Check cache first
        const cachedRecords = this.dnsCache.get(domain);
        if (cachedRecords) {
            logger.log('debug', `Using cached MX records for domain: ${domain}`);
            return cachedRecords;
        }
        try {
            // Use smartmail's getMxRecords method
            const records = await this.validator.getMxRecords(domain);
            // Store in cache (TTL is handled by the LRU cache configuration)
            this.dnsCache.set(domain, records);
            logger.log('debug', `Cached MX records for domain: ${domain}`);
            return records;
        }
        catch (error) {
            logger.log('error', `Error fetching MX records for ${domain}: ${error.message}`);
            return [];
        }
    }
    /**
     * Validates multiple email addresses in batch
     * @param emails Array of emails to validate
     * @param options Validation options
     * @returns Object with email addresses as keys and validation results as values
     */
    async validateBatch(emails, options = {}) {
        const results = {};
        for (const email of emails) {
            results[email] = await this.validate(email, options);
        }
        return results;
    }
    /**
     * Quick check if an email format is valid (synchronous, no DNS checks)
     * @param email Email to check
     * @returns Boolean indicating if format is valid
     */
    isValidFormat(email) {
        return this.validator.isValidEmailFormat(email);
    }
}
//# sourceMappingURL=data:application/json;base64, 