/**
 * Splunk HEC Client
 *
 * HTTP Event Collector client for Splunk integration.
 *
 * @module integrations/siem/splunk
 */
import { logger } from "../../logger.js";
import { formatForSplunk } from "./format.js";
/**
 * Splunk HTTP Event Collector client
 */
export class SplunkClient {
    provider = "splunk";
    config;
    abortController = null;
    constructor(config) {
        this.config = config;
    }
    /**
     * Test connection to Splunk HEC
     */
    async testConnection() {
        const startTime = Date.now();
        try {
            const response = await fetch(`${this.config.endpoint}/services/collector/health`, {
                method: "GET",
                headers: {
                    Authorization: `Splunk ${this.config.token}`,
                },
                signal: AbortSignal.timeout(10000),
            });
            const latencyMs = Date.now() - startTime;
            if (response.ok) {
                return {
                    success: true,
                    provider: "splunk",
                    endpoint: this.config.endpoint,
                    latencyMs,
                    details: { status: response.status },
                };
            }
            const text = await response.text();
            return {
                success: false,
                provider: "splunk",
                endpoint: this.config.endpoint,
                latencyMs,
                error: `HTTP ${response.status}: ${text}`,
            };
        }
        catch (error) {
            return {
                success: false,
                provider: "splunk",
                endpoint: this.config.endpoint,
                latencyMs: Date.now() - startTime,
                error: error instanceof Error ? error.message : String(error),
            };
        }
    }
    /**
     * Send a single event to Splunk
     */
    async sendEvent(event) {
        const timestamp = new Date().toISOString();
        try {
            const payload = formatForSplunk(event, {
                index: this.config.options?.index,
                source: this.config.options?.source,
                sourceType: this.config.options?.sourceType,
                host: this.config.options?.host,
            });
            const response = await fetch(`${this.config.endpoint}/services/collector/event`, {
                method: "POST",
                headers: {
                    Authorization: `Splunk ${this.config.token}`,
                    "Content-Type": "application/json",
                },
                body: JSON.stringify(payload),
                signal: AbortSignal.timeout(30000),
            });
            if (response.ok) {
                const result = await response.json();
                logger.debug("siem.splunk.event_sent", {
                    eventType: event.eventType,
                    code: result.code,
                });
                return {
                    success: true,
                    timestamp,
                };
            }
            const errorText = await response.text();
            logger.warn("siem.splunk.send_failed", {
                status: response.status,
                error: errorText,
            });
            return {
                success: false,
                timestamp,
                error: `HTTP ${response.status}: ${errorText}`,
            };
        }
        catch (error) {
            const errorMessage = error instanceof Error ? error.message : String(error);
            logger.error("siem.splunk.send_error", { error: errorMessage });
            return {
                success: false,
                timestamp,
                error: errorMessage,
            };
        }
    }
    /**
     * Send multiple events in batch
     */
    async sendEvents(events) {
        if (events.length === 0) {
            return {
                success: true,
                totalEvents: 0,
                successCount: 0,
                failureCount: 0,
            };
        }
        try {
            // Splunk HEC supports newline-delimited JSON for batch
            const payloads = events.map((event) => formatForSplunk(event, {
                index: this.config.options?.index,
                source: this.config.options?.source,
                sourceType: this.config.options?.sourceType,
                host: this.config.options?.host,
            }));
            const body = payloads.map((p) => JSON.stringify(p)).join("\n");
            const response = await fetch(`${this.config.endpoint}/services/collector/event`, {
                method: "POST",
                headers: {
                    Authorization: `Splunk ${this.config.token}`,
                    "Content-Type": "application/json",
                },
                body,
                signal: AbortSignal.timeout(60000),
            });
            if (response.ok) {
                logger.info("siem.splunk.batch_sent", {
                    eventCount: events.length,
                });
                return {
                    success: true,
                    totalEvents: events.length,
                    successCount: events.length,
                    failureCount: 0,
                };
            }
            const errorText = await response.text();
            logger.warn("siem.splunk.batch_failed", {
                status: response.status,
                error: errorText,
                eventCount: events.length,
            });
            return {
                success: false,
                totalEvents: events.length,
                successCount: 0,
                failureCount: events.length,
                errors: [{ index: 0, error: `HTTP ${response.status}: ${errorText}` }],
            };
        }
        catch (error) {
            const errorMessage = error instanceof Error ? error.message : String(error);
            logger.error("siem.splunk.batch_error", { error: errorMessage });
            return {
                success: false,
                totalEvents: events.length,
                successCount: 0,
                failureCount: events.length,
                errors: [{ index: 0, error: errorMessage }],
            };
        }
    }
    /**
     * Close connection
     */
    async close() {
        if (this.abortController) {
            this.abortController.abort();
            this.abortController = null;
        }
    }
}
/**
 * Create a Splunk client from configuration
 */
export function createSplunkClient(config) {
    return new SplunkClient({
        provider: "splunk",
        enabled: true,
        endpoint: config.endpoint.replace(/\/$/, ""),
        token: config.token,
        options: {
            index: config.index,
            sourceType: config.sourceType || "_json",
            source: config.source || "vaspera:hardening",
            host: config.host,
            verifySsl: config.verifySsl,
        },
    });
}
//# sourceMappingURL=splunk.js.map