/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { IRandom } from "@fluid-private/stochastic-test-utils";
import { ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
import { SegmentGroup } from "../mergeTreeNodes.js";
import { IMergeTreeOp } from "../ops.js";
import { TestClient } from "./testClient.js";
import { TestClientLogger } from "./testClientLogger.js";
export type TestOperation = (client: TestClient, opStart: number, opEnd: number, random: IRandom) => IMergeTreeOp[] | IMergeTreeOp | undefined;
export declare const removeRange: TestOperation;
export declare const obliterateRange: TestOperation;
export declare const obliterateRangeSided: TestOperation;
export declare const annotateRange: TestOperation;
export declare const insertAtRefPos: TestOperation;
export declare const insert: TestOperation;
export interface IConfigRange {
    min: number;
    max: number;
    growthFunc?: (input: number) => number;
}
export declare function doOverRange(range: IConfigRange, defaultGrowthFunc: (input: number) => number, doAction: (current: number) => void): void;
export declare function resolveRange(range: IConfigRange, defaultGrowthFunc: (input: number) => number): number[];
export declare function resolveRanges<T extends object>(ranges: T, defaultGrowthFunc: (input: number) => number): ResolvedRanges<T>;
type ReplaceRangeWith<T, TReplace> = T extends {
    min: number;
    max: number;
} ? TReplace : never;
type RangePropertyNames<T> = {
    [K in keyof T]-?: T[K] extends IConfigRange ? K : never;
}[keyof T];
type PickFromRanges<T> = {
    [K in RangePropertyNames<T>]: ReplaceRangeWith<T[K], number>;
};
type ResolvedRanges<T> = {
    [K in RangePropertyNames<T>]: ReplaceRangeWith<T[K], number[]>;
};
interface ProvidesGrowthFunc {
    growthFunc: (input: number) => number;
}
export declare function doOverRanges<T extends ProvidesGrowthFunc>(ranges: T, doAction: (selection: PickFromRanges<T>, description: string) => void): void;
export interface IMergeTreeOperationRunnerConfig {
    readonly rounds: number;
    readonly opsPerRoundRange: IConfigRange;
    readonly incrementalLog?: boolean;
    readonly operations: readonly TestOperation[];
    readonly applyOpDuringGeneration?: boolean;
    growthFunc(input: number): number;
    resultsFilePostfix?: string;
    insertText?: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined;
    updateEndpoints?: (client: TestClient, random: IRandom) => {
        start: number;
        end: number;
    };
}
export interface ReplayGroup {
    msgs: ISequencedDocumentMessage[];
    initialText: string;
    resultText: string;
    seq: number;
}
export declare const replayResultsPath: string;
export declare function runMergeTreeOperationRunner(random: IRandom, startingSeq: number, clients: readonly TestClient[], minLength: number, config: IMergeTreeOperationRunnerConfig, apply?: ApplyMessagesFn): number;
export declare function generateOperationMessagesForClients(random: IRandom, startingSeq: number, clients: readonly TestClient[], logger: TestClientLogger, opsPerRound: number, minLength: number, operations: readonly TestOperation[], applyOpDuringGeneration?: boolean, insertText?: (client: TestClient, random: IRandom) => IMergeTreeOp | undefined): [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][];
export declare function generateClientNames(): string[];
type ApplyMessagesFn = (startingSeq: number, messageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][], clients: readonly TestClient[], logger: TestClientLogger, random: IRandom) => number;
export declare function applyMessages(startingSeq: number, messageData: [ISequencedDocumentMessage, SegmentGroup | SegmentGroup[]][], clients: readonly TestClient[], logger: TestClientLogger): number;
export {};
//# sourceMappingURL=mergeTreeOperationRunner.d.ts.map