/**
 * 统一的SSE事件流写入器
 * 处理backpressure、超时、心跳、错误处理等通用流管理逻辑
 */
import { defaultResponsesEventSerializer, serializeAnthropicEventToSSE, serializeGeminiEventToSSE } from './serializers/index.js';
import { TimeUtils } from './utils.js';
import { serializeChatEventToSSE } from './chat-serializer.js';
/**
 * 统一的SSE流写入器
 */
export class StreamWriter {
    stream;
    config;
    stats;
    heartbeatInterval;
    isActive = true;
    writeQueue = [];
    isWriting = false;
    constructor(stream, config = {}) {
        this.stream = stream;
        this.config = {
            timeoutMs: config.timeoutMs || 30000,
            enableHeartbeat: config.enableHeartbeat ?? false,
            heartbeatIntervalMs: config.heartbeatIntervalMs || 15000,
            maxBufferSize: config.maxBufferSize || 1000,
            enableBackpressure: config.enableBackpressure ?? true,
            onEvent: config.onEvent || (() => { }),
            onError: config.onError || (() => { }),
            onComplete: config.onComplete || (() => { })
        };
        this.stats = {
            totalEvents: 0,
            bytesWritten: 0,
            startTime: TimeUtils.now(),
            lastWriteTime: 0,
            errors: 0
        };
        this.setupHeartbeat();
        this.setupErrorHandling();
    }
    /**
     * 设置心跳
     */
    setupHeartbeat() {
        if (!this.config.enableHeartbeat)
            return;
        this.heartbeatInterval = setInterval(() => {
            if (this.isActive) {
                this.sendHeartbeat();
            }
        }, this.config.heartbeatIntervalMs);
    }
    /**
     * 设置错误处理
     */
    setupErrorHandling() {
        this.stream.on('error', (error) => {
            this.stats.errors++;
            this.config.onError(error);
        });
        this.stream.on('close', () => {
            this.cleanup();
            this.config.onComplete();
        });
    }
    /**
     * 发送心跳事件
     */
    sendHeartbeat() {
        const heartbeatEvent = {
            type: 'heartbeat',
            timestamp: TimeUtils.now(),
            data: '',
            sequenceNumber: -1
        };
        this.writeEvent(heartbeatEvent);
    }
    /**
     * 写入单个事件
     */
    async writeEvent(event) {
        if (!this.isActive)
            return;
        try {
            // 触发事件回调
            this.config.onEvent(event);
            // 序列化事件 - 使用协议标识进行类型识别
            let serialized;
            if (event && event.protocol === 'chat') {
                serialized = serializeChatEventToSSE(event);
            }
            else if (event && event.protocol === 'responses') {
                serialized = this.serializeResponsesEvent(event);
            }
            else if (event && event.protocol === 'anthropic-messages') {
                serialized = serializeAnthropicEventToSSE(event);
            }
            else if (event && event.protocol === 'gemini-chat') {
                serialized = serializeGeminiEventToSSE(event);
            }
            else {
                // 兜底处理：尝试通过事件字段识别
                const eventField = event.event;
                if (eventField === 'chat_chunk' || eventField === 'chat.done' || eventField === 'error' || eventField === 'ping') {
                    serialized = serializeChatEventToSSE(event);
                }
                else if (eventField === 'message_start' || eventField === 'content_block_start') {
                    serialized = serializeAnthropicEventToSSE(event);
                }
                else if (eventField === 'gemini.data' || eventField === 'gemini.done') {
                    serialized = serializeGeminiEventToSSE(event);
                }
                else {
                    serialized = this.serializeResponsesEvent(event);
                }
            }
            const needsBackpressure = this.config.enableBackpressure && !this.stream.write(serialized);
            if (needsBackpressure) {
                await this.handleBackpressure();
            }
            // 更新统计
            this.stats.totalEvents++;
            this.stats.bytesWritten += Buffer.byteLength(serialized, 'utf8');
            this.stats.lastWriteTime = TimeUtils.now();
        }
        catch (error) {
            this.stats.errors++;
            this.config.onError(error);
        }
    }
    /**
     * 处理背压
     */
    async handleBackpressure() {
        return new Promise((resolve) => {
            const checkDrain = () => {
                if (this.stream.writableLength < this.config.maxBufferSize) {
                    this.stream.removeListener('drain', checkDrain);
                    resolve();
                }
            };
            this.stream.on('drain', checkDrain);
        });
    }
    /**
     * 序列化Responses事件（临时实现，需要 ResponsesSerializer）
     * TODO: 等Responses协议修复后，实现完整的ResponsesSerializer
     * 当前为临时实现，仅用于避免编译错误
     */
    serializeResponsesEvent(event) {
        try {
            if (typeof event.type === 'string' && event.type.startsWith('response.')) {
                return defaultResponsesEventSerializer.serializeToWire(event);
            }
        }
        catch {
            // ignore and fallback
        }
        const eventType = String(event.type ?? 'response.unknown');
        const rawData = event.data;
        const timestamp = typeof event.timestamp === 'number' ? event.timestamp : undefined;
        const sequenceNumber = typeof event.sequenceNumber === 'number' ? event.sequenceNumber : undefined;
        let wire = `event: ${eventType}\n`;
        if (rawData === '[DONE]') {
            wire += 'data: [DONE]\n';
        }
        else if (typeof rawData === 'string') {
            wire += `data: ${rawData}\n`;
        }
        else {
            const payload = rawData && typeof rawData === 'object' ? { ...rawData } : {};
            if (!Object.prototype.hasOwnProperty.call(payload, 'type'))
                payload.type = eventType;
            if (sequenceNumber !== undefined && !Object.prototype.hasOwnProperty.call(payload, 'sequence_number')) {
                payload.sequence_number = sequenceNumber;
            }
            wire += `data: ${JSON.stringify(payload)}\n`;
        }
        if (timestamp !== undefined) {
            wire += `id: ${timestamp}\n`;
        }
        wire += '\n';
        return wire;
    }
    /**
     * 异步写入事件流
     */
    async writeEventStream(events) {
        if (!this.isActive)
            return;
        try {
            for await (const event of events) {
                if (!this.isActive)
                    break;
                await this.writeEvent(event);
            }
        }
        catch (error) {
            this.stats.errors++;
            this.config.onError(error);
        }
    }
    /**
     * 同步写入事件数组
     */
    async writeEvents(events) {
        if (!this.isActive)
            return;
        for (const event of events) {
            if (!this.isActive)
                break;
            await this.writeEvent(event);
        }
    }
    /**
     * 写入Chat事件流
     */
    async writeChatEvents(events) {
        await this.writeEventStream(events);
    }
    /**
     * 写入Responses事件流
     */
    async writeResponsesEvents(events) {
        await this.writeEventStream(events);
    }
    /**
     * 写入Anthropic事件流
     */
    async writeAnthropicEvents(events) {
        await this.writeEventStream(events);
    }
    /**
     * 写入Gemini事件流
     */
    async writeGeminiEvents(events) {
        await this.writeEventStream(events);
    }
    /**
     * 完成流写入
     */
    complete() {
        if (!this.isActive)
            return;
        this.isActive = false;
        // 确保所有数据都写入完成
        if (this.stream.writable) {
            this.stream.end();
        }
    }
    /**
     * 中止流写入
     */
    abort(error) {
        if (!this.isActive)
            return;
        this.isActive = false;
        if (error) {
            this.stats.errors++;
            this.config.onError(error);
        }
        if (this.stream.writable) {
            this.stream.destroy(error);
        }
    }
    /**
     * 获取写入统计
     */
    getStats() {
        return {
            ...this.stats,
            duration: TimeUtils.now() - this.stats.startTime
        };
    }
    /**
     * 检查流是否活跃
     */
    isStreamActive() {
        return this.isActive && this.stream.writable;
    }
    /**
     * 清理资源
     */
    cleanup() {
        this.isActive = false;
        if (this.heartbeatInterval) {
            clearInterval(this.heartbeatInterval);
            this.heartbeatInterval = undefined;
        }
    }
    /**
     * 获取底层流
     */
    getUnderlyingStream() {
        return this.stream;
    }
}
/**
 * 创建Chat流写入器工厂函数
 */
export function createChatStreamWriter(stream, config = {}) {
    return new StreamWriter(stream, config);
}
/**
 * 创建Responses流写入器工厂函数
 */
export function createResponsesStreamWriter(stream, config = {}) {
    return new StreamWriter(stream, config);
}
/**
 * 创建Anthropic流写入器工厂函数
 */
export function createAnthropicStreamWriter(stream, config = {}) {
    return new StreamWriter(stream, config);
}
/**
 * 创建Gemini流写入器工厂函数
 */
export function createGeminiStreamWriter(stream, config = {}) {
    return new StreamWriter(stream, config);
}
