import * as plugins from '../plugins.js';
import { logger } from '../logger.js';
/**
 * Log level for security events
 */
export var SecurityLogLevel;
(function (SecurityLogLevel) {
    SecurityLogLevel["INFO"] = "info";
    SecurityLogLevel["WARN"] = "warn";
    SecurityLogLevel["ERROR"] = "error";
    SecurityLogLevel["CRITICAL"] = "critical";
})(SecurityLogLevel || (SecurityLogLevel = {}));
/**
 * Security event types for categorization
 */
export var SecurityEventType;
(function (SecurityEventType) {
    SecurityEventType["AUTHENTICATION"] = "authentication";
    SecurityEventType["ACCESS_CONTROL"] = "access_control";
    SecurityEventType["EMAIL_VALIDATION"] = "email_validation";
    SecurityEventType["EMAIL_PROCESSING"] = "email_processing";
    SecurityEventType["EMAIL_FORWARDING"] = "email_forwarding";
    SecurityEventType["EMAIL_DELIVERY"] = "email_delivery";
    SecurityEventType["DKIM"] = "dkim";
    SecurityEventType["SPF"] = "spf";
    SecurityEventType["DMARC"] = "dmarc";
    SecurityEventType["RATE_LIMIT"] = "rate_limit";
    SecurityEventType["RATE_LIMITING"] = "rate_limiting";
    SecurityEventType["SPAM"] = "spam";
    SecurityEventType["MALWARE"] = "malware";
    SecurityEventType["CONNECTION"] = "connection";
    SecurityEventType["DATA_EXPOSURE"] = "data_exposure";
    SecurityEventType["CONFIGURATION"] = "configuration";
    SecurityEventType["IP_REPUTATION"] = "ip_reputation";
    SecurityEventType["REJECTED_CONNECTION"] = "rejected_connection";
})(SecurityEventType || (SecurityEventType = {}));
/**
 * Security logger for enhanced security monitoring
 */
export class SecurityLogger {
    static instance;
    securityEvents = [];
    maxEventHistory;
    enableNotifications;
    constructor(options) {
        this.maxEventHistory = options?.maxEventHistory || 1000;
        this.enableNotifications = options?.enableNotifications || false;
    }
    /**
     * Get singleton instance
     */
    static getInstance(options) {
        if (!SecurityLogger.instance) {
            SecurityLogger.instance = new SecurityLogger(options);
        }
        return SecurityLogger.instance;
    }
    /**
     * Reset the singleton instance (for shutdown/testing)
     */
    static resetInstance() {
        SecurityLogger.instance = undefined;
    }
    /**
     * Log a security event
     * @param event The security event to log
     */
    logEvent(event) {
        const fullEvent = {
            ...event,
            timestamp: Date.now()
        };
        // Store in memory buffer
        this.securityEvents.push(fullEvent);
        // Trim history if needed
        if (this.securityEvents.length > this.maxEventHistory) {
            this.securityEvents.shift();
        }
        // Log to regular logger with appropriate level
        switch (event.level) {
            case SecurityLogLevel.INFO:
                logger.log('info', `[SECURITY:${event.type}] ${event.message}`, event.details);
                break;
            case SecurityLogLevel.WARN:
                logger.log('warn', `[SECURITY:${event.type}] ${event.message}`, event.details);
                break;
            case SecurityLogLevel.ERROR:
            case SecurityLogLevel.CRITICAL:
                logger.log('error', `[SECURITY:${event.type}] ${event.message}`, event.details);
                // Send notification for critical events if enabled
                if (event.level === SecurityLogLevel.CRITICAL && this.enableNotifications) {
                    this.sendNotification(fullEvent);
                }
                break;
        }
    }
    /**
     * Get recent security events
     * @param limit Maximum number of events to return
     * @param filter Filter for specific event types
     * @returns Recent security events
     */
    getRecentEvents(limit = 100, filter) {
        let filteredEvents = this.securityEvents;
        // Apply filters
        if (filter) {
            if (filter.level) {
                filteredEvents = filteredEvents.filter(event => event.level === filter.level);
            }
            if (filter.type) {
                filteredEvents = filteredEvents.filter(event => event.type === filter.type);
            }
            if (filter.fromTimestamp) {
                const fromTs = filter.fromTimestamp;
                filteredEvents = filteredEvents.filter(event => event.timestamp >= fromTs);
            }
            if (filter.toTimestamp) {
                const toTs = filter.toTimestamp;
                filteredEvents = filteredEvents.filter(event => event.timestamp <= toTs);
            }
        }
        // Return most recent events up to limit (slice first to avoid mutating source)
        return filteredEvents
            .slice()
            .sort((a, b) => b.timestamp - a.timestamp)
            .slice(0, limit);
    }
    /**
     * Get events by security level
     * @param level The security level to filter by
     * @param limit Maximum number of events to return
     * @returns Security events matching the level
     */
    getEventsByLevel(level, limit = 100) {
        return this.getRecentEvents(limit, { level });
    }
    /**
     * Get events by security type
     * @param type The event type to filter by
     * @param limit Maximum number of events to return
     * @returns Security events matching the type
     */
    getEventsByType(type, limit = 100) {
        return this.getRecentEvents(limit, { type });
    }
    /**
     * Get security events for a specific IP address
     * @param ipAddress The IP address to filter by
     * @param limit Maximum number of events to return
     * @returns Security events for the IP address
     */
    getEventsByIP(ipAddress, limit = 100) {
        return this.securityEvents
            .filter(event => event.ipAddress === ipAddress)
            .sort((a, b) => b.timestamp - a.timestamp)
            .slice(0, limit);
    }
    /**
     * Get security events for a specific domain
     * @param domain The domain to filter by
     * @param limit Maximum number of events to return
     * @returns Security events for the domain
     */
    getEventsByDomain(domain, limit = 100) {
        return this.securityEvents
            .filter(event => event.domain === domain)
            .sort((a, b) => b.timestamp - a.timestamp)
            .slice(0, limit);
    }
    /**
     * Send a notification for critical security events
     * @param event The security event to notify about
     * @private
     */
    sendNotification(event) {
        // In a production environment, this would integrate with a notification service
        // For now, we'll just log that we would send a notification
        logger.log('error', `[SECURITY NOTIFICATION] ${event.message}`, {
            ...event,
            notificationSent: true
        });
        // Future integration with alerting systems would go here
    }
    /**
     * Clear event history
     */
    clearEvents() {
        this.securityEvents = [];
    }
    /**
     * Get statistical summary of security events
     * @param timeWindow Optional time window in milliseconds
     * @returns Summary of security events
     */
    getEventsSummary(timeWindow) {
        const cutoff = timeWindow ? Date.now() - timeWindow : 0;
        // Initialize counters
        const byLevel = {};
        for (const level of Object.values(SecurityLogLevel)) {
            byLevel[level] = 0;
        }
        const byType = {};
        for (const type of Object.values(SecurityEventType)) {
            byType[type] = 0;
        }
        const ipCounts = new Map();
        const domainCounts = new Map();
        // Single pass over all events
        let total = 0;
        for (const e of this.securityEvents) {
            if (cutoff && e.timestamp < cutoff)
                continue;
            total++;
            byLevel[e.level]++;
            byType[e.type]++;
            if (e.ipAddress) {
                ipCounts.set(e.ipAddress, (ipCounts.get(e.ipAddress) || 0) + 1);
            }
            if (e.domain) {
                domainCounts.set(e.domain, (domainCounts.get(e.domain) || 0) + 1);
            }
        }
        // Sort and limit top entries
        const topIPs = Array.from(ipCounts.entries())
            .map(([ip, count]) => ({ ip, count }))
            .sort((a, b) => b.count - a.count)
            .slice(0, 10);
        const topDomains = Array.from(domainCounts.entries())
            .map(([domain, count]) => ({ domain, count }))
            .sort((a, b) => b.count - a.count)
            .slice(0, 10);
        return { total, byLevel, byType, topIPs, topDomains };
    }
}
//# sourceMappingURL=data:application/json;base64, 