/**
 * Shared Fragment Handler for Protocol Detection
 *
 * Provides unified fragment buffering and reassembly for protocols
 * that may span multiple TCP packets.
 */
import { Buffer } from 'node:buffer';
/**
 * Shared fragment handler for protocol detection
 */
export class FragmentHandler {
    constructor(options = {}) {
        this.options = options;
        this.fragments = new Map();
        // Start cleanup timer if not already running
        if (options.cleanupInterval && !this.cleanupTimer) {
            this.cleanupTimer = setInterval(() => this.cleanup(), options.cleanupInterval);
            // Don't let this timer prevent process exit
            if (this.cleanupTimer.unref) {
                this.cleanupTimer.unref();
            }
        }
    }
    /**
     * Add a fragment for a connection
     */
    addFragment(connectionId, fragment) {
        const existing = this.fragments.get(connectionId);
        if (existing) {
            // Append to existing buffer
            const newBuffer = Buffer.concat([existing.buffer, fragment]);
            // Check size limit
            const maxSize = this.options.maxBufferSize || 65536;
            if (newBuffer.length > maxSize) {
                this.fragments.delete(connectionId);
                return {
                    isComplete: false,
                    needsMoreData: false,
                    error: 'Buffer size exceeded maximum allowed'
                };
            }
            // Update fragment info
            this.fragments.set(connectionId, {
                buffer: newBuffer,
                timestamp: Date.now(),
                connectionId
            });
            return {
                isComplete: false,
                buffer: newBuffer,
                needsMoreData: true
            };
        }
        else {
            // New fragment
            this.fragments.set(connectionId, {
                buffer: fragment,
                timestamp: Date.now(),
                connectionId
            });
            return {
                isComplete: false,
                buffer: fragment,
                needsMoreData: true
            };
        }
    }
    /**
     * Get the current buffer for a connection
     */
    getBuffer(connectionId) {
        return this.fragments.get(connectionId)?.buffer;
    }
    /**
     * Mark a connection as complete and clean up
     */
    complete(connectionId) {
        this.fragments.delete(connectionId);
    }
    /**
     * Check if we're tracking a connection
     */
    hasConnection(connectionId) {
        return this.fragments.has(connectionId);
    }
    /**
     * Clean up expired fragments
     */
    cleanup() {
        const now = Date.now();
        const timeout = this.options.timeout || 5000;
        for (const [connectionId, info] of this.fragments.entries()) {
            if (now - info.timestamp > timeout) {
                this.fragments.delete(connectionId);
            }
        }
    }
    /**
     * Clear all fragments
     */
    clear() {
        this.fragments.clear();
    }
    /**
     * Destroy the handler and clean up resources
     */
    destroy() {
        if (this.cleanupTimer) {
            clearInterval(this.cleanupTimer);
            this.cleanupTimer = undefined;
        }
        this.clear();
    }
    /**
     * Get the number of tracked connections
     */
    get size() {
        return this.fragments.size;
    }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJhZ21lbnQtaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RzL3Byb3RvY29scy9jb21tb24vZnJhZ21lbnQtaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxhQUFhLENBQUM7QUE4QnJDOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGVBQWU7SUFJMUIsWUFBb0IsVUFBNEIsRUFBRTtRQUE5QixZQUFPLEdBQVAsT0FBTyxDQUF1QjtRQUgxQyxjQUFTLEdBQUcsSUFBSSxHQUFHLEVBQXlCLENBQUM7UUFJbkQsNkNBQTZDO1FBQzdDLElBQUksT0FBTyxDQUFDLGVBQWUsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNsRCxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FDN0IsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUNwQixPQUFPLENBQUMsZUFBZSxDQUN4QixDQUFDO1lBQ0YsNENBQTRDO1lBQzVDLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDNUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUM1QixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILFdBQVcsQ0FBQyxZQUFvQixFQUFFLFFBQWdCO1FBQ2hELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRWxELElBQUksUUFBUSxFQUFFLENBQUM7WUFDYiw0QkFBNEI7WUFDNUIsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztZQUU3RCxtQkFBbUI7WUFDbkIsTUFBTSxPQUFPLEdBQUcsSUFBSSxD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