import { ExportResultCode } from '@opentelemetry/core';
import { existsSync, appendFileSync, mkdirSync } from 'node:fs';
import { join } from 'node:path';
import { randomUUID } from 'node:crypto';
/**
 * JSONL implementation of the LogRecordExporter interface
 * Writes logs to a timestamped JSONL file
 */
export class JSONLLogExporter {
    currentFile = null;
    basePath;
    filePrefix;
    /**
     * Creates a new JSONL log record exporter
     * @param basePath - Directory to store the JSONL files
     */
    constructor(basePath) {
        this.basePath = basePath;
        this.filePrefix = 'otel-log';
        this.ensureDirectory();
    }
    ensureDirectory() {
        if (!existsSync(this.basePath)) {
            mkdirSync(this.basePath, { recursive: true });
        }
    }
    getOrCreateFile() {
        // If current file exists, use it
        if (this.currentFile && existsSync(this.currentFile)) {
            return this.currentFile;
        }
        this.currentFile = join(this.basePath, `${this.filePrefix}-${Date.now()}.${randomUUID()}.jsonl`);
        return this.currentFile;
    }
    /**
     * Exports log records to a JSONL file
     *
     * @param logs - The log records to export
     * @param resultCallback - Callback function to report the export result
     */
    export(logs, resultCallback) {
        try {
            if (logs.length === 0) {
                resultCallback({ code: ExportResultCode.SUCCESS });
                return;
            }
            const file = this.getOrCreateFile();
            const lines = [];
            for (const log of logs) {
                const record = {
                    timestamp: log.hrTime,
                    observedTimestamp: log.hrTimeObserved,
                    severityNumber: log.severityNumber,
                    severityText: log.severityText,
                    body: log.body,
                    attributes: log.attributes,
                    resource: log.resource.attributes,
                    instrumentationScope: log.instrumentationScope,
                    spanContext: log.spanContext,
                };
                lines.push(JSON.stringify(record));
            }
            const payload = `${lines.join('\n')}\n`;
            try {
                appendFileSync(file, payload, 'utf-8');
            }
            catch (err) {
                // File may have been deleted, reset and retry once
                const code = err.code;
                if (code === 'ENOENT') {
                    this.currentFile = null;
                    const newFile = this.getOrCreateFile();
                    appendFileSync(newFile, payload, 'utf-8');
                }
                else {
                    throw err;
                }
            }
            resultCallback({ code: ExportResultCode.SUCCESS });
        }
        catch (error) {
            resultCallback({
                code: ExportResultCode.FAILED,
                error: error instanceof Error ? error : new Error(String(error)),
            });
        }
    }
    /**
     * Shuts down the exporter
     *
     * @returns A promise that resolves when shutdown is complete
     */
    async shutdown() {
        this.currentFile = null;
    }
    /**
     * Forces a flush of any pending data
     */
    async forceFlush() {
        // No-op for file-based exporter as writes are synchronous
    }
}
//# sourceMappingURL=jsonl-log-exporter.js.map