import * as plugins from '../../plugins.js';
import { logger } from '../../logger.js';
import { SecurityLogger, SecurityLogLevel, SecurityEventType } from '../../security/index.js';
import { RustSecurityBridge } from '../../security/classes.rustsecuritybridge.js';
/**
 * SPF result qualifiers
 */
export var SpfQualifier;
(function (SpfQualifier) {
    SpfQualifier["PASS"] = "+";
    SpfQualifier["NEUTRAL"] = "?";
    SpfQualifier["SOFTFAIL"] = "~";
    SpfQualifier["FAIL"] = "-";
})(SpfQualifier || (SpfQualifier = {}));
/**
 * SPF mechanism types
 */
export var SpfMechanismType;
(function (SpfMechanismType) {
    SpfMechanismType["ALL"] = "all";
    SpfMechanismType["INCLUDE"] = "include";
    SpfMechanismType["A"] = "a";
    SpfMechanismType["MX"] = "mx";
    SpfMechanismType["IP4"] = "ip4";
    SpfMechanismType["IP6"] = "ip6";
    SpfMechanismType["EXISTS"] = "exists";
    SpfMechanismType["REDIRECT"] = "redirect";
    SpfMechanismType["EXP"] = "exp";
})(SpfMechanismType || (SpfMechanismType = {}));
/**
 * Class for verifying SPF records.
 * Delegates actual SPF evaluation to the Rust security bridge.
 * Retains parseSpfRecord() for lightweight local parsing.
 */
export class SpfVerifier {
    constructor(_dnsManager) {
        // dnsManager is no longer needed — Rust handles DNS lookups
    }
    /**
     * Parse SPF record from TXT record (pure string parsing, no DNS)
     */
    parseSpfRecord(record) {
        if (!record.startsWith('v=spf1')) {
            return null;
        }
        try {
            const spfRecord = {
                version: 'spf1',
                mechanisms: [],
                modifiers: {}
            };
            const terms = record.split(' ').filter(term => term.length > 0);
            for (let i = 1; i < terms.length; i++) {
                const term = terms[i];
                if (term.includes('=')) {
                    const [name, value] = term.split('=');
                    spfRecord.modifiers[name] = value;
                    continue;
                }
                let qualifier = SpfQualifier.PASS;
                let mechanismText = term;
                if (term.startsWith('+') || term.startsWith('-') ||
                    term.startsWith('~') || term.startsWith('?')) {
                    qualifier = term[0];
                    mechanismText = term.substring(1);
                }
                const colonIndex = mechanismText.indexOf(':');
                let type;
                let value;
                if (colonIndex !== -1) {
                    type = mechanismText.substring(0, colonIndex);
                    value = mechanismText.substring(colonIndex + 1);
                }
                else {
                    type = mechanismText;
                }
                spfRecord.mechanisms.push({ qualifier, type, value });
            }
            return spfRecord;
        }
        catch (error) {
            logger.log('error', `Error parsing SPF record: ${error.message}`, {
                record,
                error: error.message
            });
            return null;
        }
    }
    /**
     * Verify SPF for a given email — delegates to Rust bridge
     */
    async verify(email, ip, heloDomain) {
        const securityLogger = SecurityLogger.getInstance();
        const mailFrom = email.from || '';
        const domain = mailFrom.split('@')[1] || '';
        try {
            const bridge = RustSecurityBridge.getInstance();
            const result = await bridge.checkSpf({
                ip,
                heloDomain,
                hostname: plugins.os.hostname(),
                mailFrom,
            });
            const spfResult = {
                result: result.result,
                domain: result.domain,
                ip: result.ip,
                explanation: result.explanation ?? undefined,
            };
            securityLogger.logEvent({
                level: spfResult.result === 'pass' ? SecurityLogLevel.INFO :
                    (spfResult.result === 'fail' ? SecurityLogLevel.WARN : SecurityLogLevel.INFO),
                type: SecurityEventType.SPF,
                message: `SPF ${spfResult.result} for ${spfResult.domain} from IP ${ip}`,
                domain: spfResult.domain,
                details: { ip, heloDomain, result: spfResult.result, explanation: spfResult.explanation },
                success: spfResult.result === 'pass'
            });
            return spfResult;
        }
        catch (error) {
            logger.log('error', `SPF verification error: ${error.message}`, { domain, ip, error: error.message });
            securityLogger.logEvent({
                level: SecurityLogLevel.ERROR,
                type: SecurityEventType.SPF,
                message: `SPF verification error for ${domain}`,
                domain,
                details: { ip, error: error.message },
                success: false
            });
            return {
                result: 'temperror',
                explanation: `Error verifying SPF: ${error.message}`,
                domain,
                ip,
                error: error.message
            };
        }
    }
    /**
     * Check if email passes SPF verification and apply headers
     */
    async verifyAndApply(email, ip, heloDomain) {
        const result = await this.verify(email, ip, heloDomain);
        email.headers['Received-SPF'] = `${result.result} (${result.domain}: ${result.explanation || ''}) client-ip=${ip}; envelope-from=${email.getEnvelopeFrom()}; helo=${heloDomain};`;
        switch (result.result) {
            case 'fail':
                email.mightBeSpam = true;
                logger.log('warn', `SPF failed for ${result.domain} from ${ip}: ${result.explanation}`);
                return false;
            case 'softfail':
                email.mightBeSpam = true;
                logger.log('info', `SPF softfailed for ${result.domain} from ${ip}: ${result.explanation}`);
                return true;
            case 'neutral':
            case 'none':
                logger.log('info', `SPF ${result.result} for ${result.domain} from ${ip}: ${result.explanation}`);
                return true;
            case 'pass':
                logger.log('info', `SPF passed for ${result.domain} from ${ip}: ${result.explanation}`);
                return true;
            case 'temperror':
            case 'permerror':
                logger.log('error', `SPF error for ${result.domain} from ${ip}: ${result.explanation}`);
                return true;
            default:
                return true;
        }
    }
}
//# sourceMappingURL=data:application/json;base64,[encoded data, 7240 characters]