/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { IBatchMessage } from "@fluidframework/container-definitions/internal";
import { ITelemetryBaseLogger } from "@fluidframework/core-interfaces";
import { ICompressionRuntimeOptions } from "../containerRuntime.js";
import { PendingMessageResubmitData, PendingStateManager } from "../pendingStateManager.js";
import { BatchSequenceNumbers, type BatchId } from "./batchManager.js";
import { LocalBatchMessage, IBatchCheckpoint, type LocalBatch, type OutboundBatch } from "./definitions.js";
import { OpCompressor } from "./opCompressor.js";
import { OpGroupingManager } from "./opGroupingManager.js";
import { OpSplitter } from "./opSplitter.js";
export interface IOutboxConfig {
    readonly compressionOptions: ICompressionRuntimeOptions;
    /**
     * The maximum size of a batch that we can send over the wire.
     */
    readonly maxBatchSizeInBytes: number;
    /**
     * If true, maybeFlushPartialBatch will flush the batch if the reference sequence number changed
     * since the batch started. Otherwise, it will throw in this case (apart from reentrancy which is handled elsewhere).
     * Once the new throw-based flow is proved in a production environment, this option will be removed.
     */
    readonly flushPartialBatches: boolean;
}
export interface IOutboxParameters {
    readonly shouldSend: () => boolean;
    readonly pendingStateManager: PendingStateManager;
    readonly submitBatchFn: ((batch: IBatchMessage[], referenceSequenceNumber?: number) => number) | undefined;
    readonly legacySendBatchFn: (batch: OutboundBatch) => number;
    readonly config: IOutboxConfig;
    readonly compressor: OpCompressor;
    readonly splitter: OpSplitter;
    readonly logger: ITelemetryBaseLogger;
    readonly groupingManager: OpGroupingManager;
    readonly getCurrentSequenceNumbers: () => BatchSequenceNumbers;
    readonly reSubmit: (message: PendingMessageResubmitData) => void;
    readonly opReentrancy: () => boolean;
}
/**
 * Temporarily increase the stack limit while executing the provided action.
 * If a negative value is provided for `length`, no stack frames will be collected.
 * If Infinity is provided, all frames will be collected.
 *
 * ADO:4663 - add this to the common packages.
 *
 * @param action - action which returns an error
 * @param length - number of stack frames to collect, 50 if unspecified.
 * @returns the result of the action provided
 */
export declare function getLongStack<T>(action: () => T, length?: number): T;
/**
 * Convert from local batch to outbound batch, including computing contentSizeInBytes.
 */
export declare function localBatchToOutboundBatch(localBatch: LocalBatch): OutboundBatch;
/**
 * Estimates the real size in bytes on the socket for a given batch. It assumes that
 * the envelope size (and the size of an empty op) is 200 bytes, taking into account
 * extra overhead from stringification.
 *
 * @remarks
 * Also content will be stringified, and that adds a lot of overhead due to a lot of escape characters.
 * Not taking it into account, as compression work should help there - compressed payload will be
 * initially stored as base64, and that requires only 2 extra escape characters.
 *
 * @param batch - the batch to inspect
 * @returns An estimate of the payload size in bytes which will be produced when the batch is sent over the wire
 */
export declare const estimateSocketSize: (batch: OutboundBatch) => number;
/**
 * The Outbox collects messages submitted by the ContainerRuntime into a batch,
 * and then flushes the batch when requested.
 *
 * @remarks There are actually multiple independent batches (some are for a specific message type),
 * to support slight variation in semantics for each batch (e.g. support for rebasing or grouping).
 */
export declare class Outbox {
    private readonly params;
    private readonly logger;
    private readonly mainBatch;
    private readonly blobAttachBatch;
    private readonly idAllocationBatch;
    private batchRebasesToReport;
    private rebasing;
    /**
     * Track the number of ops which were detected to have a mismatched
     * reference sequence number, in order to self-throttle the telemetry events.
     *
     * This should be removed as part of ADO:2322
     */
    private readonly maxMismatchedOpsToReport;
    private mismatchedOpsReported;
    constructor(params: IOutboxParameters);
    get messageCount(): number;
    get mainBatchMessageCount(): number;
    get blobAttachBatchMessageCount(): number;
    get idAllocationBatchMessageCount(): number;
    get isEmpty(): boolean;
    /**
     * Detect whether batching has been interrupted by an incoming message being processed. In this case,
     * we will flush the accumulated messages to account for that (if allowed) and create a new batch with the new
     * message as the first message. If flushing partial batch is not enabled, we will throw (except for reentrant ops).
     * This would indicate we expected this case to be precluded by logic elsewhere.
     *
     * @remarks - To detect batch interruption, we compare both the reference sequence number
     * (i.e. last message processed by DeltaManager) and the client sequence number of the
     * last message processed by the ContainerRuntime. In the absence of op reentrancy, this
     * pair will remain stable during a single JS turn during which the batch is being built up.
     */
    private maybeFlushPartialBatch;
    submit(message: LocalBatchMessage): void;
    submitBlobAttach(message: LocalBatchMessage): void;
    submitIdAllocation(message: LocalBatchMessage): void;
    private addMessageToBatchManager;
    /**
     * Flush all the batches to the ordering service.
     * This method is expected to be called at the end of a batch.
     *
     * @throws If called from a reentrant context, or if the batch being flushed is too large.
     * @param resubmittingBatchId - If defined, indicates this is a resubmission of a batch
     * with the given Batch ID, which must be preserved
     */
    flush(resubmittingBatchId?: BatchId): void;
    private flushAll;
    private flushEmptyBatch;
    private flushInternal;
    /**
     * Rebases a batch. All the ops in the batch are resubmitted to the runtime and
     * they will end up back in the same batch manager they were flushed from and subsequently flushed.
     *
     * @param rawBatch - the batch to be rebased
     */
    private rebase;
    private isContextReentrant;
    /**
     * As necessary and enabled, groups / compresses / chunks the given batch.
     *
     * @remarks - If chunking happens, a side effect here is that 1 or more chunks are queued immediately for sending in next JS turn.
     *
     * @param localBatch - Local Batch to be virtualized - i.e. transformed into an Outbound Batch
     * @param groupingEnabled - If true, Grouped batching is enabled.
     * @returns One of the following:
     * - (A) The original batch (Based on what's enabled)
     * - (B) A grouped batch (it's a singleton batch)
     * - (C) A compressed singleton batch
     * - (D) A singleton batch containing the last chunk.
     */
    private virtualizeBatch;
    /**
     * Sends the batch object to the container context to be sent over the wire.
     *
     * @param batch - batch to be sent
     * @returns the clientSequenceNumber of the start of the batch, or undefined if nothing was sent
     */
    private sendBatch;
    private makeBatchTooLargeError;
    /**
     * Gets a checkpoint object per batch that facilitates iterating over the batch messages when rolling back.
     */
    getBatchCheckpoints(): {
        mainBatch: IBatchCheckpoint;
        idAllocationBatch: IBatchCheckpoint;
        blobAttachBatch: IBatchCheckpoint;
    };
}
//# sourceMappingURL=outbox.d.ts.map