import * as plugins from '../plugins.js';
import * as paths from '../paths.js';
import { logger } from '../logger.js';
// ---------------------------------------------------------------------------
// RustSecurityBridge — singleton wrapper around smartrust.RustBridge
// ---------------------------------------------------------------------------
/**
 * Bridge between TypeScript and the Rust `mailer-bin` binary.
 *
 * Uses `@push.rocks/smartrust` for JSON-over-stdin/stdout IPC.
 * Singleton — access via `RustSecurityBridge.getInstance()`.
 */
export class RustSecurityBridge {
    static instance = null;
    bridge;
    _running = false;
    constructor() {
        this.bridge = new plugins.smartrust.RustBridge({
            binaryName: 'mailer-bin',
            cliArgs: ['--management'],
            requestTimeoutMs: 30_000,
            readyTimeoutMs: 10_000,
            localPaths: [
                plugins.path.join(paths.packageDir, 'dist_rust', 'mailer-bin'),
                plugins.path.join(paths.packageDir, 'rust', 'target', 'release', 'mailer-bin'),
                plugins.path.join(paths.packageDir, 'rust', 'target', 'debug', 'mailer-bin'),
            ],
            searchSystemPath: false,
        });
        // Forward lifecycle events
        this.bridge.on('ready', () => {
            this._running = true;
            logger.log('info', 'Rust security bridge is ready');
        });
        this.bridge.on('exit', (code, signal) => {
            this._running = false;
            logger.log('warn', `Rust security bridge exited (code=${code}, signal=${signal})`);
        });
        this.bridge.on('stderr', (line) => {
            logger.log('debug', `[rust-bridge] ${line}`);
        });
    }
    /** Get or create the singleton instance. */
    static getInstance() {
        if (!RustSecurityBridge.instance) {
            RustSecurityBridge.instance = new RustSecurityBridge();
        }
        return RustSecurityBridge.instance;
    }
    /** Whether the Rust process is currently running and accepting commands. */
    get running() {
        return this._running;
    }
    // -----------------------------------------------------------------------
    // Lifecycle
    // -----------------------------------------------------------------------
    /**
     * Spawn the Rust binary and wait for the ready signal.
     * @returns `true` if the binary started successfully, `false` otherwise.
     */
    async start() {
        if (this._running) {
            return true;
        }
        try {
            const ok = await this.bridge.spawn();
            this._running = ok;
            if (ok) {
                logger.log('info', 'Rust security bridge started');
            }
            else {
                logger.log('warn', 'Rust security bridge failed to start (binary not found or timeout)');
            }
            return ok;
        }
        catch (err) {
            logger.log('error', `Failed to start Rust security bridge: ${err.message}`);
            return false;
        }
    }
    /** Kill the Rust process. */
    async stop() {
        if (!this._running) {
            return;
        }
        try {
            this.bridge.kill();
            this._running = false;
            logger.log('info', 'Rust security bridge stopped');
        }
        catch (err) {
            logger.log('error', `Error stopping Rust security bridge: ${err.message}`);
        }
    }
    // -----------------------------------------------------------------------
    // Commands — thin typed wrappers over sendCommand
    // -----------------------------------------------------------------------
    /** Ping the Rust process. */
    async ping() {
        const res = await this.bridge.sendCommand('ping', {});
        return res?.pong === true;
    }
    /** Get version information for all Rust crates. */
    async getVersion() {
        return this.bridge.sendCommand('version', {});
    }
    /** Validate an email address. */
    async validateEmail(email) {
        return this.bridge.sendCommand('validateEmail', { email });
    }
    /** Detect bounce type from SMTP response / diagnostic code. */
    async detectBounce(opts) {
        return this.bridge.sendCommand('detectBounce', opts);
    }
    /** Check IP reputation via DNSBL. */
    async checkIpReputation(ip) {
        return this.bridge.sendCommand('checkIpReputation', { ip });
    }
    /** Verify DKIM signatures on a raw email message. */
    async verifyDkim(rawMessage) {
        return this.bridge.sendCommand('verifyDkim', { rawMessage });
    }
    /** Sign an email with DKIM. */
    async signDkim(opts) {
        return this.bridge.sendCommand('signDkim', opts);
    }
    /** Check SPF for a sender. */
    async checkSpf(opts) {
        return this.bridge.sendCommand('checkSpf', opts);
    }
    /**
     * Compound email security verification: DKIM + SPF + DMARC in one IPC call.
     *
     * This is the preferred method for inbound email verification — it avoids
     * 3 sequential round-trips and correctly passes raw mail-auth types internally.
     */
    async verifyEmail(opts) {
        return this.bridge.sendCommand('verifyEmail', opts);
    }
}
//# sourceMappingURL=data:application/json;base64, 