/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { IFluidHandle, type IEventThisPlaceHolder } from "@fluidframework/core-interfaces";
import { IFluidSerializer } from "@fluidframework/shared-object-base";
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
import { IFluidDataStoreRuntime, IChannelStorageService } from "@fluidframework/datastore-definitions";
import { ISummaryTreeWithStats } from "@fluidframework/runtime-definitions";
import { TypedEventEmitter } from "@fluid-internal/client-utils";
import { ITelemetryLoggerExt } from "@fluidframework/telemetry-utils";
import { LocalReferencePosition, SlidingPreference } from "./localReference";
import { CollaborationWindow, ISegment, ISegmentAction, Marker, SegmentGroup } from "./mergeTreeNodes";
import { IJSONSegment, IMergeTreeAnnotateMsg, IMergeTreeDeltaOp, IMergeTreeGroupMsg, IMergeTreeInsertMsg, IMergeTreeRemoveMsg, IMergeTreeOp, IRelativePosition, ReferenceType, IMergeTreeObliterateMsg } from "./ops";
import { PropertySet } from "./properties";
import { IMergeTreeTextHelper } from "./textSegment";
import { ReferencePosition } from "./referencePositions";
import { IMergeTreeOptions } from "./mergeTree";
import { IMergeTreeDeltaCallbackArgs, IMergeTreeDeltaOpArgs, IMergeTreeMaintenanceCallbackArgs } from "./index";
/**
 * A range [start, end)
 * @internal
 */
export interface IIntegerRange {
    start: number;
    end: number;
}
/**
 * Emitted before this client's merge-tree normalizes its segments on reconnect, potentially
 * ordering them. Useful for DDS-like consumers built atop the merge-tree to compute any information
 * they need for rebasing their ops on reconnection.
 * @alpha
 */
export interface IClientEvents {
    (event: "normalize", listener: (target: IEventThisPlaceHolder) => void): void;
    (event: "delta", listener: (opArgs: IMergeTreeDeltaOpArgs, deltaArgs: IMergeTreeDeltaCallbackArgs, target: IEventThisPlaceHolder) => void): void;
    (event: "maintenance", listener: (args: IMergeTreeMaintenanceCallbackArgs, deltaArgs: IMergeTreeDeltaOpArgs | undefined, target: IEventThisPlaceHolder) => void): void;
}
/**
 * @deprecated This functionality was not meant to be exported and will be removed in a future release
 * @alpha
 */
export declare class Client extends TypedEventEmitter<IClientEvents> {
    readonly specToSegment: (spec: IJSONSegment) => ISegment;
    readonly logger: ITelemetryLoggerExt;
    longClientId: string | undefined;
    private readonly _mergeTree;
    private readonly clientNameToIds;
    private readonly shortClientIdMap;
    constructor(specToSegment: (spec: IJSONSegment) => ISegment, logger: ITelemetryLoggerExt, options?: IMergeTreeOptions & PropertySet);
    /**
     * The merge tree maintains a queue of segment groups for each local operation.
     * These segment groups track segments modified by an operation.
     * This method peeks the tail of that queue, and returns the segments groups there.
     * It is used to get the segment group(s) for the previous operations.
     * @param count - The number segment groups to get peek from the tail of the queue. Default 1.
     */
    peekPendingSegmentGroups(): SegmentGroup | undefined;
    peekPendingSegmentGroups(count: number): SegmentGroup | SegmentGroup[] | undefined;
    /**
     * Annotates the markers with the provided properties
     * @param marker - The marker to annotate
     * @param props - The properties to annotate the marker with
     * @returns The annotate op if valid, otherwise undefined
     */
    annotateMarker(marker: Marker, props: PropertySet): IMergeTreeAnnotateMsg | undefined;
    /**
     * Annotates the range with the provided properties
     * @param start - The inclusive start position of the range to annotate
     * @param end - The exclusive end position of the range to annotate
     * @param props - The properties to annotate the range with
     * @returns The annotate op if valid, otherwise undefined
     */
    annotateRangeLocal(start: number, end: number, props: PropertySet): IMergeTreeAnnotateMsg | undefined;
    /**
     * Removes the range
     *
     * @param start - The inclusive start of the range to remove
     * @param end - The exclusive end of the range to remove
     */
    removeRangeLocal(start: number, end: number): IMergeTreeRemoveMsg;
    /**
     * Obliterates the range. This is similar to removing the range, but also
     * includes any concurrently inserted content.
     *
     * @param start - The inclusive start of the range to obliterate
     * @param end - The exclusive end of the range to obliterate
     */
    obliterateRangeLocal(start: number, end: number): IMergeTreeObliterateMsg;
    /**
     * @param pos - The position to insert the segment at
     * @param segment - The segment to insert
     */
    insertSegmentLocal(pos: number, segment: ISegment): IMergeTreeInsertMsg | undefined;
    /**
     * @param refPos - The reference position to insert the segment at
     * @param segment - The segment to insert
     */
    insertAtReferencePositionLocal(refPos: ReferencePosition, segment: ISegment): IMergeTreeInsertMsg | undefined;
    walkSegments<TClientData>(handler: ISegmentAction<TClientData>, start: number | undefined, end: number | undefined, accum: TClientData, splitRange?: boolean): void;
    walkSegments<undefined>(handler: ISegmentAction<undefined>, start?: number, end?: number, accum?: undefined, splitRange?: boolean): void;
    protected walkAllSegments<TClientData>(action: (segment: ISegment, accum?: TClientData) => boolean, accum?: TClientData): boolean;
    /**
     * Serializes the data required for garbage collection. The IFluidHandles stored in all segments that haven't
     * been removed represent routes to other objects. We serialize the data in these segments using the passed in
     * serializer which keeps track of all serialized handles.
     */
    serializeGCData(handle: IFluidHandle, handleCollectingSerializer: IFluidSerializer): void;
    getCollabWindow(): CollaborationWindow;
    /**
     * Returns the current position of a segment, and -1 if the segment
     * does not exist in this merge tree
     * @param segment - The segment to get the position of
     */
    getPosition(segment: ISegment | undefined, localSeq?: number): number;
    /**
     * Creates a `LocalReferencePosition` on this client. If the refType does not include ReferenceType.Transient,
     * the returned reference will be added to the localRefs on the provided segment.
     * @param segment - Segment to add the local reference on
     * @param offset - Offset on the segment at which to place the local reference
     * @param refType - ReferenceType for the created local reference
     * @param properties - PropertySet to place on the created local reference
     * @param canSlideToEndpoint - Whether or not the created local reference can
     * slide onto one of the special endpoint segments denoting the position
     * before the start of or after the end of the tree
     */
    createLocalReferencePosition(segment: ISegment | "start" | "end", offset: number | undefined, refType: ReferenceType, properties: PropertySet | undefined, slidingPreference?: SlidingPreference, canSlideToEndpoint?: boolean): LocalReferencePosition;
    /**
     * Removes a `LocalReferencePosition` from this client.
     */
    removeLocalReferencePosition(lref: LocalReferencePosition): LocalReferencePosition | undefined;
    /**
     * Resolves a `ReferencePosition` into a character position using this client's perspective.
     */
    localReferencePositionToPosition(lref: ReferencePosition): number;
    /**
     * Given a position specified relative to a marker id, lookup the marker
     * and convert the position to a character position.
     * @param relativePos - Id of marker (may be indirect) and whether position is before or after marker.
     */
    posFromRelativePos(relativePos: IRelativePosition): number;
    getMarkerFromId(id: string): ISegment | undefined;
    /**
     * Revert an op
     */
    rollback?(op: any, localOpMetadata: unknown): void;
    private applyObliterateRangeOp;
    /**
     * Performs the remove based on the provided op
     * @param opArgs - The ops args for the op
     */
    private applyRemoveRangeOp;
    /**
     * Performs the annotate based on the provided op
     * @param opArgs - The ops args for the op
     */
    private applyAnnotateRangeOp;
    /**
     * Performs the insert based on the provided op
     * @param opArgs - The ops args for the op
     * @returns True if the insert was applied. False if it could not be.
     */
    private applyInsertOp;
    /**
     * Returns a valid range for the op, or undefined
     * @param op - The op to generate the range for
     * @param clientArgs - The client args for the op
     */
    private getValidOpRange;
    /**
     * Gets the client args from the op if remote, otherwise uses the local clients info
     * @param sequencedMessage - The sequencedMessage to get the client sequence args for
     */
    private getClientSequenceArgsForMessage;
    /**
     * Gets the client args from the op if remote, otherwise uses the local clients info
     * @param opArgs - The op arg to get the client sequence args for
     */
    private getClientSequenceArgs;
    private ackPendingSegment;
    getOrAddShortClientId(longClientId: string): number;
    protected getShortClientId(longClientId: string): number;
    getLongClientId(shortClientId: number): string;
    addLongClientId(longClientId: string): void;
    private getOrAddShortClientIdFromMessage;
    /**
     * During reconnect, we must find the positions to pending segments
     * relative to other pending segments. This methods computes that
     * position relative to a localSeq. Pending segments above the localSeq
     * will be ignored.
     *
     * @param segment - The segment to find the position for
     * @param localSeq - The localSeq to find the position of the segment at
     */
    findReconnectionPosition(segment: ISegment, localSeq: number): number;
    private resetPendingDeltaToOps;
    private applyRemoteOp;
    applyStashedOp(op: IMergeTreeDeltaOp): SegmentGroup;
    applyStashedOp(op: IMergeTreeGroupMsg): SegmentGroup[];
    applyStashedOp(op: IMergeTreeOp): SegmentGroup | SegmentGroup[];
    applyMsg(msg: ISequencedDocumentMessage, local?: boolean): void;
    private updateSeqNumbers;
    /**
     * Resolves a remote client's position against the local sequence
     * and returns the remote client's position relative to the local
     * sequence
     * @param remoteClientPosition - The remote client's position to resolve
     * @param remoteClientRefSeq - The reference sequence number of the remote client
     * @param remoteClientId - The client id of the remote client
     */
    resolveRemoteClientPosition(remoteClientPosition: number, remoteClientRefSeq: number, remoteClientId: string): number | undefined;
    private lastNormalizationRefSeq;
    private pendingRebase;
    /**
     * Given a pending operation and segment group, regenerate the op, so it
     * can be resubmitted
     * @param resetOp - The op to reset
     * @param segmentGroup - The segment group associated with the op
     */
    regeneratePendingOp(resetOp: IMergeTreeOp, segmentGroup: SegmentGroup | SegmentGroup[]): IMergeTreeOp;
    createTextHelper(): IMergeTreeTextHelper;
    summarize(runtime: IFluidDataStoreRuntime, handle: IFluidHandle, serializer: IFluidSerializer, catchUpMsgs: ISequencedDocumentMessage[]): ISummaryTreeWithStats;
    load(runtime: IFluidDataStoreRuntime, storage: IChannelStorageService, serializer: IFluidSerializer): Promise<{
        catchupOpsP: Promise<ISequencedDocumentMessage[]>;
    }>;
    private getLocalSequenceNumber;
    localTransaction(groupOp: IMergeTreeGroupMsg): void;
    updateMinSeq(minSeq: number): void;
    getContainingSegment<T extends ISegment>(pos: number, sequenceArgs?: Pick<ISequencedDocumentMessage, "referenceSequenceNumber" | "clientId">, localSeq?: number): {
        segment: T | undefined;
        offset: number | undefined;
    };
    getPropertiesAtPosition(pos: number): PropertySet | undefined;
    getRangeExtentsOfPosition(pos: number): {
        posStart: number | undefined;
        posAfterEnd: number | undefined;
    };
    getCurrentSeq(): number;
    getClientId(): number;
    getLength(): number;
    startOrUpdateCollaboration(longClientId: string | undefined, minSeq?: number, currentSeq?: number): void;
    /**
     * @deprecated Use searchForMarker instead.
     */
    findTile(startPos: number, tileLabel: string, preceding?: boolean): {
        tile: ReferencePosition;
        pos: number;
    } | undefined;
    /**
     * Searches a string for the nearest marker in either direction to a given start position.
     * The search will include the start position, so markers at the start position are valid
     * results of the search. Makes use of block-accelerated search functions for log(n) complexity.
     *
     * @param startPos - Position at which to start the search
     * @param markerLabel - Label of the marker to search for
     * @param forwards - Whether the desired marker comes before (false) or after (true) `startPos`
     */
    searchForMarker(startPos: number, markerLabel: string, forwards?: boolean): Marker | undefined;
}
//# sourceMappingURL=client.d.ts.map