/**
 * Blue Team Logging Module
 *
 * Purpose: Comprehensive attack chain logging for defensive security analysis
 * Use Case: Red team assessment with client authorization
 *
 * This module provides detailed telemetry for blue team defenders to:
 * 1. Understand the complete attack chain
 * 2. Identify detection opportunities
 * 3. Validate security control effectiveness
 * 4. Improve defensive capabilities
 *
 * IMPORTANT: This logging module should be deployed in authorized penetration
 * testing environments only. It captures detailed telemetry about evasion
 * techniques to help security teams improve their detection capabilities.
 */

class BlueTeamLogger {
    constructor(config = {}) {
        this.sessionId = this.generateSessionId();
        this.startTime = Date.now();
        this.logs = [];
        this.detectionEvents = [];
        this.config = {
            logToConsole: config.logToConsole !== false, // Default true
            logToServer: config.logToServer || false,
            serverEndpoint: config.serverEndpoint || '/api/blue-team-logs',
            bufferSize: config.bufferSize || 100,
            ...config
        };

        this.initializeLogging();
    }

    generateSessionId() {
        return `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
    }

    initializeLogging() {
        this.logEvent('SESSION_START', {
            sessionId: this.sessionId,
            timestamp: new Date().toISOString(),
            userAgent: navigator.userAgent,
            url: window.location.href,
            referrer: document.referrer
        });

        // Hook into window.onerror for error tracking
        const originalOnError = window.onerror;
        window.onerror = (message, source, lineno, colno, error) => {
            this.logEvent('ERROR', {
                message,
                source,
                lineno,
                colno,
                stack: error?.stack
            });
            if (originalOnError) {
                return originalOnError(message, source, lineno, colno, error);
            }
        };
    }

    logEvent(eventType, data) {
        const event = {
            sessionId: this.sessionId,
            eventType,
            timestamp: Date.now(),
            relativeTime: Date.now() - this.startTime,
            data,
            stackTrace: new Error().stack
        };

        this.logs.push(event);

        if (this.config.logToConsole) {
            console.log(`[BlueTeam] ${eventType}:`, data);
        }

        // Buffer and send to server if configured
        if (this.config.logToServer && this.logs.length >= this.config.bufferSize) {
            this.flushLogsToServer();
        }

        return event;
    }

    // Detection-specific logging
    logDetection(module, technique, result, metadata = {}) {
        const detectionEvent = {
            module,
            technique,
            result,
            metadata,
            timestamp: Date.now()
        };

        this.detectionEvents.push(detectionEvent);

        this.logEvent('DETECTION', {
            module,
            technique,
            result,
            score: metadata.score || 0,
            details: metadata
        });

        return detectionEvent;
    }

    // Hardware fingerprinting logging
    logHardwareFingerprint(type, data) {
        this.logEvent('HARDWARE_FINGERPRINT', {
            type, // 'gpu', 'webgl', 'audio'
            data,
            timestamp: Date.now()
        });
    }

    // API call logging for detection
    logAPICall(api, method, parameters, result) {
        this.logEvent('API_CALL', {
            api, // 'WebGL', 'AudioContext', 'Canvas'
            method,
            parameters,
            result,
            timestamp: Date.now()
        });
    }

    // Behavioral analysis logging
    logBehavior(behaviorType, metrics) {
        this.logEvent('BEHAVIOR_ANALYSIS', {
            behaviorType, // 'mouse_entropy', 'interaction', 'touch_entropy'
            metrics,
            timestamp: Date.now()
        });
    }

    // Performance analysis logging
    logPerformance(analysisType, measurements) {
        this.logEvent('PERFORMANCE_ANALYSIS', {
            analysisType, // 'execution_timing', 'raf_jitter'
            measurements,
            timestamp: Date.now()
        });
    }

    // Network activity logging
    logNetworkActivity(url, method, payload, response) {
        this.logEvent('NETWORK_ACTIVITY', {
            url,
            method,
            payloadSize: payload ? JSON.stringify(payload).length : 0,
            responseStatus: response?.status,
            timestamp: Date.now()
        });
    }

    // Anti-forensics detection logging
    logAntiForensics(technique, details) {
        this.logEvent('ANTI_FORENSICS', {
            technique, // 'console_obliteration', 'dom_sanitization', 'history_manipulation'
            details,
            timestamp: Date.now(),
            severity: 'CRITICAL'
        });
    }

    // Data exfiltration logging
    logExfiltration(destination, dataType, size) {
        this.logEvent('DATA_EXFILTRATION', {
            destination,
            dataType,
            size,
            timestamp: Date.now(),
            severity: 'CRITICAL'
        });
    }

    // Generate attack chain summary
    generateAttackChain() {
        const chain = {
            sessionId: this.sessionId,
            duration: Date.now() - this.startTime,
            totalEvents: this.logs.length,
            detectionEvents: this.detectionEvents.length,
            phases: this.categorizePhases(),
            timeline: this.logs.map(log => ({
                time: log.relativeTime,
                event: log.eventType,
                details: log.data
            })),
            mitreTactics: this.mapToMITRE(),
            indicators: this.extractIOCs()
        };

        return chain;
    }

    categorizePhases() {
        const phases = {
            reconnaissance: [],
            environmentDetection: [],
            behavioralAnalysis: [],
            antiForensics: [],
            exfiltration: []
        };

        this.logs.forEach(log => {
            switch (log.eventType) {
                case 'HARDWARE_FINGERPRINT':
                case 'API_CALL':
                    phases.reconnaissance.push(log);
                    phases.environmentDetection.push(log);
                    break;
                case 'DETECTION':
                    phases.environmentDetection.push(log);
                    break;
                case 'BEHAVIOR_ANALYSIS':
                    phases.behavioralAnalysis.push(log);
                    break;
                case 'ANTI_FORENSICS':
                    phases.antiForensics.push(log);
                    break;
                case 'DATA_EXFILTRATION':
                case 'NETWORK_ACTIVITY':
                    phases.exfiltration.push(log);
                    break;
            }
        });

        return phases;
    }

    mapToMITRE() {
        const tactics = new Set();

        this.logs.forEach(log => {
            switch (log.eventType) {
                case 'DETECTION':
                    tactics.add('T1497 - Virtualization/Sandbox Evasion');
                    break;
                case 'ANTI_FORENSICS':
                    tactics.add('T1070 - Indicator Removal');
                    tactics.add('T1562 - Impair Defenses');
                    break;
                case 'DATA_EXFILTRATION':
                    tactics.add('T1567 - Exfiltration Over Web Service');
                    break;
            }
        });

        return Array.from(tactics);
    }

    extractIOCs() {
        const iocs = {
            domains: new Set(),
            ips: new Set(),
            urls: new Set(),
            techniques: new Set()
        };

        this.logs.forEach(log => {
            if (log.eventType === 'NETWORK_ACTIVITY') {
                try {
                    const url = new URL(log.data.url);
                    iocs.domains.add(url.hostname);
                    iocs.urls.add(log.data.url);
                } catch (e) {
                    // Invalid URL
                }
            }
            if (log.eventType === 'DETECTION') {
                iocs.techniques.add(log.data.technique);
            }
        });

        return {
            domains: Array.from(iocs.domains),
            urls: Array.from(iocs.urls),
            techniques: Array.from(iocs.techniques)
        };
    }

    // Export logs for analysis
    exportLogs(format = 'json') {
        const exportData = {
            sessionId: this.sessionId,
            startTime: new Date(this.startTime).toISOString(),
            endTime: new Date().toISOString(),
            duration: Date.now() - this.startTime,
            logs: this.logs,
            detectionEvents: this.detectionEvents,
            attackChain: this.generateAttackChain()
        };

        switch (format) {
            case 'json':
                return JSON.stringify(exportData, null, 2);
            case 'csv':
                return this.convertToCSV(exportData.logs);
            case 'siem':
                return this.formatForSIEM(exportData);
            default:
                return exportData;
        }
    }

    convertToCSV(logs) {
        const headers = ['Timestamp', 'Event Type', 'Module', 'Technique', 'Details'];
        const rows = [headers];

        logs.forEach(log => {
            rows.push([
                new Date(log.timestamp).toISOString(),
                log.eventType,
                log.data.module || '',
                log.data.technique || '',
                JSON.stringify(log.data)
            ]);
        });

        return rows.map(row => row.join(',')).join('\n');
    }

    formatForSIEM(exportData) {
        // Common Event Format (CEF) for SIEM ingestion
        return exportData.logs.map(log => {
            return `CEF:0|BlueTeamLogger|EvasionDetection|1.0|${log.eventType}|${log.data.technique || log.eventType}|${this.getSeverity(log)}|rt=${log.timestamp} sessionId=${this.sessionId} msg=${JSON.stringify(log.data)}`;
        }).join('\n');
    }

    getSeverity(log) {
        if (log.data.severity === 'CRITICAL') return 10;
        if (log.eventType === 'DATA_EXFILTRATION') return 9;
        if (log.eventType === 'ANTI_FORENSICS') return 8;
        if (log.eventType === 'DETECTION') return 6;
        return 3;
    }

    async flushLogsToServer() {
        if (!this.config.logToServer) return;

        try {
            const response = await fetch(this.config.serverEndpoint, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    sessionId: this.sessionId,
                    logs: this.logs
                })
            });

            if (response.ok) {
                console.log('[BlueTeam] Logs successfully sent to server');
                this.logs = []; // Clear buffer after successful send
            }
        } catch (error) {
            console.error('[BlueTeam] Failed to send logs to server:', error);
        }
    }

    // Download logs for offline analysis
    downloadLogs(filename = `blue-team-logs-${this.sessionId}.json`) {
        const dataStr = this.exportLogs('json');
        const dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);

        const exportFileDefaultName = filename;

        const linkElement = document.createElement('a');
        linkElement.setAttribute('href', dataUri);
        linkElement.setAttribute('download', exportFileDefaultName);
        linkElement.click();
    }

    // Real-time alert generation
    generateAlert(severity, message, details) {
        const alert = {
            severity, // 'INFO', 'WARNING', 'CRITICAL'
            message,
            details,
            timestamp: Date.now(),
            sessionId: this.sessionId
        };

        this.logEvent('ALERT', alert);

        // Could integrate with alerting systems here
        if (severity === 'CRITICAL' && this.config.logToConsole) {
            console.warn(`[BlueTeam] CRITICAL ALERT: ${message}`, details);
        }

        return alert;
    }
}

// Global initialization
window.BlueTeamLogger = BlueTeamLogger;

// Auto-initialize if config is provided
if (window.blueTeamConfig) {
    window.blueTeamLogger = new BlueTeamLogger(window.blueTeamConfig);
}

/**
 * USAGE EXAMPLES:
 *
 * // Initialize logger
 * const logger = new BlueTeamLogger({
 *     logToConsole: true,
 *     logToServer: true,
 *     serverEndpoint: '/api/security-logs'
 * });
 *
 * // Log detection events
 * logger.logDetection('WebGL', 'gpu_fingerprint', { renderer: 'SwiftShader' }, { score: 3 });
 *
 * // Log API calls
 * logger.logAPICall('WebGL', 'readPixels', { width: 64, height: 64 }, 'success');
 *
 * // Log anti-forensics activity
 * logger.logAntiForensics('console_obliteration', { methods: ['log', 'warn', 'error'] });
 *
 * // Generate attack chain report
 * const attackChain = logger.generateAttackChain();
 * console.log(attackChain);
 *
 * // Export for analysis
 * logger.downloadLogs();
 */
