/**
 * SIEM Event Formatting
 *
 * Converts Vaspera events to SIEM-compatible formats (CEF, JSON).
 *
 * @module integrations/siem/format
 */
const DEVICE_VENDOR = "Vaspera";
const DEVICE_PRODUCT = "Hardening MCP";
const DEVICE_VERSION = "2.11.0";
/**
 * Map Vaspera severity to SIEM severity
 */
export function mapSeverity(severity) {
    switch (severity) {
        case "critical":
            return "critical";
        case "high":
            return "high";
        case "medium":
            return "medium";
        case "low":
            return "low";
        case "info":
            return "informational";
        default:
            return "informational";
    }
}
/**
 * Map SIEM severity to CEF numeric severity (0-10)
 */
export function severityToCEF(severity) {
    switch (severity) {
        case "critical":
            return 10;
        case "high":
            return 8;
        case "medium":
            return 5;
        case "low":
            return 3;
        case "informational":
            return 1;
        default:
            return 0;
    }
}
/**
 * Map event type to signature ID
 */
function eventTypeToSignatureId(eventType) {
    const mapping = {
        "finding.new": "VASP-001",
        "finding.fixed": "VASP-002",
        "finding.false_positive": "VASP-003",
        "scan.started": "VASP-010",
        "scan.completed": "VASP-011",
        "scan.failed": "VASP-012",
        "certification.started": "VASP-020",
        "certification.completed": "VASP-021",
        "compliance.report": "VASP-030",
        "autofix.applied": "VASP-040",
        "autofix.pr_created": "VASP-041",
    };
    return mapping[eventType] || "VASP-999";
}
/**
 * Map event type to human-readable name
 */
function eventTypeToName(eventType) {
    const mapping = {
        "finding.new": "New Security Finding",
        "finding.fixed": "Security Finding Fixed",
        "finding.false_positive": "Finding Marked False Positive",
        "scan.started": "Security Scan Started",
        "scan.completed": "Security Scan Completed",
        "scan.failed": "Security Scan Failed",
        "certification.started": "Certification Started",
        "certification.completed": "Certification Completed",
        "compliance.report": "Compliance Report Generated",
        "autofix.applied": "Autofix Applied",
        "autofix.pr_created": "Autofix Pull Request Created",
    };
    return mapping[eventType] || "Unknown Event";
}
/**
 * Escape CEF special characters
 */
function escapeCEF(value) {
    return value
        .replace(/\\/g, "\\\\")
        .replace(/=/g, "\\=")
        .replace(/\|/g, "\\|")
        .replace(/\n/g, "\\n")
        .replace(/\r/g, "\\r");
}
/**
 * Format event as CEF string
 */
export function formatAsCEF(event) {
    const fields = {
        version: 0,
        deviceVendor: DEVICE_VENDOR,
        deviceProduct: DEVICE_PRODUCT,
        deviceVersion: DEVICE_VERSION,
        signatureId: eventTypeToSignatureId(event.eventType),
        name: eventTypeToName(event.eventType),
        severity: severityToCEF(event.severity),
        extension: {},
    };
    // Build extension fields
    const ext = fields.extension;
    ext["rt"] = new Date(event.timestamp).getTime();
    ext["msg"] = escapeCEF(event.message);
    ext["src"] = event.source;
    ext["cs1"] = event.project;
    ext["cs1Label"] = "project";
    if (event.certificationId) {
        ext["cs2"] = event.certificationId;
        ext["cs2Label"] = "certificationId";
    }
    // Add finding-specific fields
    const data = event.data;
    if (data.findingId) {
        ext["externalId"] = data.findingId;
    }
    if (data.file) {
        ext["filePath"] = escapeCEF(data.file);
    }
    if (data.line) {
        ext["fileId"] = data.line;
    }
    if (data.category) {
        ext["cat"] = escapeCEF(data.category);
    }
    if (data.scanner) {
        ext["deviceCustomString3"] = escapeCEF(data.scanner);
        ext["deviceCustomString3Label"] = "scanner";
    }
    if (data.ruleId) {
        ext["cs4"] = escapeCEF(data.ruleId);
        ext["cs4Label"] = "ruleId";
    }
    if (data.cweIds && data.cweIds.length > 0) {
        ext["cs5"] = data.cweIds.join(",");
        ext["cs5Label"] = "cweIds";
    }
    // Format CEF header
    const header = [
        `CEF:${fields.version}`,
        escapeCEF(fields.deviceVendor),
        escapeCEF(fields.deviceProduct),
        escapeCEF(fields.deviceVersion),
        escapeCEF(fields.signatureId),
        escapeCEF(fields.name),
        fields.severity.toString(),
    ].join("|");
    // Format extension
    const extension = Object.entries(ext)
        .map(([key, value]) => `${key}=${value}`)
        .join(" ");
    return `${header}|${extension}`;
}
/**
 * Format event as JSON for generic SIEM ingestion
 */
export function formatAsJSON(event) {
    return {
        "@timestamp": event.timestamp,
        event: {
            kind: "event",
            category: ["security"],
            type: [event.eventType.split(".")[0]],
            action: event.eventType,
            severity: severityToCEF(event.severity),
            severity_name: event.severity,
        },
        message: event.message,
        source: {
            provider: event.source,
            version: DEVICE_VERSION,
        },
        project: {
            path: event.project,
            certification_id: event.certificationId,
        },
        vaspera: event.data,
    };
}
/**
 * Format event for Splunk HEC
 */
export function formatForSplunk(event, options = {}) {
    return {
        time: Math.floor(new Date(event.timestamp).getTime() / 1000),
        host: options.host || "vaspera",
        source: options.source || "vaspera:hardening",
        sourcetype: options.sourceType || "_json",
        index: options.index,
        event: formatAsJSON(event),
    };
}
/**
 * Format event for Microsoft Sentinel (Log Analytics)
 */
export function formatForSentinel(event) {
    const json = formatAsJSON(event);
    return {
        TimeGenerated: event.timestamp,
        EventType_s: event.eventType,
        Severity_s: event.severity,
        Project_s: event.project,
        CertificationId_g: event.certificationId || "",
        Message_s: event.message,
        Source_s: event.source,
        RawEvent_s: JSON.stringify(event.data),
        ...flattenData(event.data, "_"),
    };
}
/**
 * Format event for Datadog
 */
export function formatForDatadog(event, options = {}) {
    const tags = [
        `project:${event.project}`,
        `event_type:${event.eventType}`,
        `severity:${event.severity}`,
        ...(event.certificationId ? [`certification_id:${event.certificationId}`] : []),
        ...(options.tags || []),
    ];
    if (options.env) {
        tags.push(`env:${options.env}`);
    }
    return {
        ddsource: "vaspera",
        ddtags: tags.join(","),
        hostname: "vaspera-mcp",
        service: options.service || "vaspera-hardening",
        status: mapSeverityToDatadogStatus(event.severity),
        message: event.message,
        "@timestamp": event.timestamp,
        event_type: event.eventType,
        project: event.project,
        certification_id: event.certificationId,
        data: event.data,
    };
}
/**
 * Map SIEM severity to Datadog status
 */
function mapSeverityToDatadogStatus(severity) {
    switch (severity) {
        case "critical":
            return "emergency";
        case "high":
            return "error";
        case "medium":
            return "warning";
        case "low":
            return "info";
        case "informational":
            return "debug";
        default:
            return "info";
    }
}
/**
 * Flatten nested data object for Sentinel
 */
function flattenData(data, suffix, prefix = "") {
    const result = {};
    for (const [key, value] of Object.entries(data)) {
        const newKey = prefix ? `${prefix}_${key}${suffix}` : `${key}${suffix}`;
        if (value === null || value === undefined) {
            continue;
        }
        if (typeof value === "object" && !Array.isArray(value)) {
            Object.assign(result, flattenData(value, suffix, key));
        }
        else if (Array.isArray(value)) {
            result[newKey] = value.join(",");
        }
        else if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
            result[newKey] = value;
        }
    }
    return result;
}
/**
 * Create a finding event
 */
export function createFindingEvent(project, eventType, finding, certificationId) {
    const actionVerb = eventType === "finding.new" ? "detected" : eventType === "finding.fixed" ? "fixed" : "marked as false positive";
    return {
        timestamp: new Date().toISOString(),
        eventType,
        severity: mapSeverity(finding.severity),
        project,
        certificationId,
        message: `Security finding ${actionVerb}: ${finding.category} in ${finding.file || "unknown"}${finding.line ? `:${finding.line}` : ""}`,
        source: "vaspera",
        data: finding,
    };
}
/**
 * Create a scan event
 */
export function createScanEvent(project, eventType, scan, certificationId) {
    let severity = "informational";
    let message;
    switch (eventType) {
        case "scan.started":
            message = `Security scan started with scanners: ${scan.scanners.join(", ")}`;
            break;
        case "scan.completed":
            severity = scan.bySeverity.critical > 0 ? "critical" : scan.bySeverity.high > 0 ? "high" : "informational";
            message = `Security scan completed: ${scan.findingsCount} findings (${scan.bySeverity.critical} critical, ${scan.bySeverity.high} high)`;
            break;
        case "scan.failed":
            severity = "high";
            message = `Security scan failed: ${scan.error || "Unknown error"}`;
            break;
    }
    return {
        timestamp: new Date().toISOString(),
        eventType,
        severity,
        project,
        certificationId,
        message,
        source: "vaspera",
        data: scan,
    };
}
/**
 * Create a certification event
 */
export function createCertificationEvent(project, eventType, certification) {
    let severity = "informational";
    let message;
    if (eventType === "certification.started") {
        message = `Certification started: ${certification.certificationId}`;
    }
    else {
        severity = certification.score && certification.score >= 80 ? "informational" : "medium";
        message = `Certification completed: ${certification.level || "unknown"} (score: ${certification.score || 0})`;
    }
    return {
        timestamp: new Date().toISOString(),
        eventType,
        severity,
        project,
        certificationId: certification.certificationId,
        message,
        source: "vaspera",
        data: certification,
    };
}
//# sourceMappingURL=format.js.map