/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { TypedEventEmitter } from "@fluid-internal/client-utils";
import { AttachState, IAudience } from "@fluidframework/container-definitions";
import { IDeltaManager } from "@fluidframework/container-definitions/internal";
import { FluidObject, IDisposable, IRequest, IResponse, type IEvent } from "@fluidframework/core-interfaces";
import { type IFluidHandleInternal } from "@fluidframework/core-interfaces/internal";
import { IClientDetails, IQuorumClients } from "@fluidframework/driver-definitions";
import { IDocumentStorageService, type ISnapshot, IDocumentMessage, ISnapshotTree, ITreeEntry, ISequencedDocumentMessage } from "@fluidframework/driver-definitions/internal";
import type { IIdCompressor } from "@fluidframework/id-compressor";
import { ISummaryTreeWithStats, ITelemetryContext, IGarbageCollectionData, CreateChildSummarizerNodeFn, CreateChildSummarizerNodeParam, IContainerRuntimeBase, IDataStore, IFluidDataStoreChannel, IFluidDataStoreContext, IFluidDataStoreContextDetached, IFluidDataStoreRegistry, IFluidParentContext, IGarbageCollectionDetailsBase, IProvideFluidDataStoreFactory, ISummarizeResult, ISummarizerNodeWithGC, SummarizeInternalFn, IInboundSignalMessage } from "@fluidframework/runtime-definitions/internal";
import { MonitoringContext } from "@fluidframework/telemetry-utils/internal";
export declare function createAttributesBlob(pkg: readonly string[], isRootDataStore: boolean): ITreeEntry;
/** @internal */
export interface ISnapshotDetails {
    pkg: readonly string[];
    isRootDataStore: boolean;
    snapshot?: ISnapshotTree;
    sequenceNumber?: number;
}
/**
 * This is interface that every context should implement.
 * This interface is used for context's parent - ChannelCollection.
 * It should not be exposed to any other users of context.
 * @internal
 */
export interface IFluidDataStoreContextInternal extends IFluidDataStoreContext {
    getAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats;
    getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData;
    getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
    realize(): Promise<IFluidDataStoreChannel>;
    isRoot(): Promise<boolean>;
}
/**
 * Properties necessary for creating a FluidDataStoreContext
 * @internal
 */
export interface IFluidDataStoreContextProps {
    readonly id: string;
    readonly parentContext: IFluidParentContext;
    readonly storage: IDocumentStorageService;
    readonly scope: FluidObject;
    readonly createSummarizerNodeFn: CreateChildSummarizerNodeFn;
    readonly pkg?: Readonly<string[]>;
    readonly loadingGroupId?: string;
}
/**
 * Properties necessary for creating a local FluidDataStoreContext
 * @internal
 */
export interface ILocalFluidDataStoreContextProps extends IFluidDataStoreContextProps {
    readonly pkg: Readonly<string[]> | undefined;
    readonly snapshotTree: ISnapshotTree | undefined;
    readonly makeLocallyVisibleFn: () => void;
    /**
     * @deprecated 0.16 Issue #1635, #3631
     */
    readonly createProps?: any;
}
/**
 * Properties necessary for creating a local FluidDataStoreContext
 * @internal
 */
export interface ILocalDetachedFluidDataStoreContextProps extends ILocalFluidDataStoreContextProps {
    readonly channelToDataStoreFn: (channel: IFluidDataStoreChannel) => IDataStore;
}
/**
 * Properties necessary for creating a remote FluidDataStoreContext
 * @internal
 */
export interface IRemoteFluidDataStoreContextProps extends IFluidDataStoreContextProps {
    readonly snapshot: ISnapshotTree | ISnapshot | undefined;
}
/** @internal */
export interface IFluidDataStoreContextEvents extends IEvent {
    (event: "attaching" | "attached", listener: () => void): any;
}
/**
 * Represents the context for the store. This context is passed to the store runtime.
 * @internal
 */
export declare abstract class FluidDataStoreContext extends TypedEventEmitter<IFluidDataStoreContextEvents> implements IFluidDataStoreContextInternal, IFluidParentContext, IDisposable {
    private readonly existing;
    readonly isLocalDataStore: boolean;
    private readonly makeLocallyVisibleFn;
    get packagePath(): readonly string[];
    get options(): Record<string | number, any>;
    get clientId(): string | undefined;
    get clientDetails(): IClientDetails;
    get baseLogger(): import("@fluidframework/core-interfaces").ITelemetryBaseLogger;
    get deltaManager(): IDeltaManager<ISequencedDocumentMessage, IDocumentMessage>;
    get connected(): boolean;
    get IFluidHandleContext(): import("@fluidframework/core-interfaces/internal").IFluidHandleContext;
    get containerRuntime(): IContainerRuntimeBase;
    ensureNoDataModelChanges<T>(callback: () => T): T;
    get isLoaded(): boolean;
    get baseSnapshot(): ISnapshotTree | undefined;
    get idCompressor(): IIdCompressor | undefined;
    private _disposed;
    get disposed(): boolean;
    /**
     * A Tombstoned object has been unreferenced long enough that GC knows it won't be referenced again.
     * Tombstoned objects are eventually deleted by GC.
     */
    private _tombstoned;
    get tombstoned(): boolean;
    /** If true, throw an error when a tombstone data store is used. */
    readonly gcThrowOnTombstoneUsage: boolean;
    readonly gcTombstoneEnforcementAllowed: boolean;
    /** If true, this means that this data store context and its children have been removed from the runtime */
    protected deleted: boolean;
    get attachState(): AttachState;
    get IFluidDataStoreRegistry(): IFluidDataStoreRegistry | undefined;
    private baseSnapshotSequenceNumber;
    /**
     * A datastore is considered as root if it
     * 1. is root in memory - see isInMemoryRoot
     * 2. is root as part of the base snapshot that the datastore loaded from
     * @returns whether a datastore is root
     */
    isRoot(aliasedDataStores?: Set<string>): Promise<boolean>;
    /**
     * There are 3 states where isInMemoryRoot needs to be true
     * 1. when a datastore becomes aliased. This can happen for both remote and local datastores
     * 2. when a datastore is created locally as root
     * 3. when a datastore is created locally as root and is rehydrated
     * @returns whether a datastore is root in memory
     */
    protected isInMemoryRoot(): boolean;
    protected registry: IFluidDataStoreRegistry | undefined;
    protected detachedRuntimeCreation: boolean;
    protected channel: IFluidDataStoreChannel | undefined;
    private loaded;
    protected pending: ISequencedDocumentMessage[] | undefined;
    protected channelP: Promise<IFluidDataStoreChannel> | undefined;
    protected _baseSnapshot: ISnapshotTree | undefined;
    protected _attachState: AttachState;
    private _isInMemoryRoot;
    protected readonly summarizerNode: ISummarizerNodeWithGC;
    protected readonly mc: MonitoringContext;
    private readonly thresholdOpsCounter;
    private static readonly pendingOpsCountThreshold;
    /**
     * If the summarizer makes local changes, a telemetry event is logged. This has the potential to be very noisy.
     * So, adding a count of how many telemetry events are logged per data store context. This can be
     * controlled via feature flags.
     */
    private localChangesTelemetryCount;
    private lastUsedRoutes;
    readonly id: string;
    private readonly _containerRuntime;
    private readonly parentContext;
    readonly storage: IDocumentStorageService;
    readonly scope: FluidObject;
    readonly loadingGroupId: string | undefined;
    protected pkg?: readonly string[];
    constructor(props: IFluidDataStoreContextProps, existing: boolean, isLocalDataStore: boolean, makeLocallyVisibleFn: () => void);
    dispose(): void;
    /**
     * When delete is called, that means that the data store is permanently removed from the runtime, and will not show up in future summaries
     * This function is called to prevent ops from being generated from this data store once it has been deleted. Furthermore, this data store
     * should not receive any ops/signals.
     */
    delete(): void;
    setTombstone(tombstone: boolean): void;
    abstract setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void;
    private rejectDeferredRealize;
    realize(): Promise<IFluidDataStoreChannel>;
    protected factoryFromPackagePath(): Promise<import("@fluidframework/runtime-definitions/internal").IFluidDataStoreFactory>;
    private realizeCore;
    /**
     * Notifies this object about changes in the connection state.
     * @param value - New connection state.
     * @param clientId - ID of the client. Its old ID when in disconnected state and
     * its new client ID when we are connecting or connected.
     */
    setConnectionState(connected: boolean, clientId?: string): void;
    process(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
    processSignal(message: IInboundSignalMessage, local: boolean): void;
    getQuorum(): IQuorumClients;
    getAudience(): IAudience;
    /**
     * Returns a summary at the current sequence number.
     * @param fullTree - true to bypass optimizations and force a full summary tree
     * @param trackState - This tells whether we should track state from this summary.
     * @param telemetryContext - summary data passed through the layers for telemetry purposes
     */
    summarize(fullTree?: boolean, trackState?: boolean, telemetryContext?: ITelemetryContext): Promise<ISummarizeResult>;
    private summarizeInternal;
    /**
     * Returns the data used for garbage collection. This includes a list of GC nodes that represent this data store
     * including any of its child channel contexts. Each node has a set of outbound routes to other GC nodes in the
     * document.
     * If there is no new data in this data store since the last summary, previous GC data is used.
     * If there is new data, the GC data is generated again (by calling getGCDataInternal).
     * @param fullGC - true to bypass optimizations and force full generation of GC data.
     */
    getGCData(fullGC?: boolean): Promise<IGarbageCollectionData>;
    /**
     * Generates data used for garbage collection. This is called when there is new data since last summary. It
     * realizes the data store and calls into each channel context to get its GC data.
     * @param fullGC - true to bypass optimizations and force full generation of GC data.
     */
    private getGCDataInternal;
    /**
     * After GC has run, called to notify the data store of routes used in it. These are used for the following:
     *
     * 1. To identify if this data store is being referenced in the document or not.
     *
     * 2. To determine if it needs to re-summarize in case used routes changed since last summary.
     *
     * 3. These are added to the summary generated by the data store.
     *
     * 4. To notify child contexts of their used routes. This is done immediately if the data store is loaded.
     * Else, it is done when realizing the data store.
     *
     * 5. To update the timestamp when this data store or any children are marked as unreferenced.
     *
     * @param usedRoutes - The routes that are used in this data store.
     */
    updateUsedRoutes(usedRoutes: string[]): void;
    /**
     * Called when a new outbound reference is added to another node. This is used by garbage collection to identify
     * all references added in the system.
     *
     * @param fromPath - The absolute path of the node that added the reference.
     * @param toPath - The absolute path of the outbound node that is referenced.
     * @param messageTimestampMs - The timestamp of the message that added the reference.
     */
    addedGCOutboundRoute(fromPath: string, toPath: string, messageTimestampMs?: number): void;
    /**
     * Updates the used routes of the channel and its child contexts. The channel must be loaded before calling this.
     * It is called in these two scenarios:
     * 1. When the used routes of the data store is updated and the data store is loaded.
     * 2. When the data store is realized. This updates the channel's used routes as per last GC run.
     */
    private updateChannelUsedRoutes;
    /**
     * @deprecated 0.18.Should call request on the runtime directly
     */
    request(request: IRequest): Promise<IResponse>;
    submitMessage(type: string, content: any, localOpMetadata: unknown): void;
    /**
     * This is called from a SharedSummaryBlock that does not generate ops but only wants to be part of the summary.
     * It indicates that there is data in the object that needs to be summarized.
     * We will update the latestSequenceNumber of the summary tracker of this
     * store and of the object's channel.
     *
     * @param address - The address of the channel that is dirty.
     *
     */
    setChannelDirty(address: string): void;
    /**
     * Submits the signal to be sent to other clients.
     * @param type - Type of the signal.
     * @param content - Content of the signal. Should be a JSON serializable object or primitive.
     * @param targetClientId - When specified, the signal is only sent to the provided client id.
     */
    submitSignal(type: string, content: unknown, targetClientId?: string): void;
    /**
     * This is called by the data store channel when it becomes locally visible indicating that it is ready to become
     * globally visible now.
     */
    makeLocallyVisible(): void;
    protected processPendingOps(channel: IFluidDataStoreChannel): void;
    protected completeBindingRuntime(channel: IFluidDataStoreChannel): void;
    protected bindRuntime(channel: IFluidDataStoreChannel, existing: boolean): Promise<void>;
    getAbsoluteUrl(relativeUrl: string): Promise<string | undefined>;
    /**
     * Get the summary required when attaching this context's DataStore.
     * Used for both Container Attach and DataStore Attach.
     */
    abstract getAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats;
    /**
     * Get the GC Data for the initial state being attached so remote clients can learn of this DataStore's
     * outbound routes.
     */
    abstract getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData;
    abstract getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
    /**
     * @deprecated Sets the datastore as root, for aliasing purposes: #7948
     * This method should not be used outside of the aliasing context.
     * It will be removed, as the source of truth for this flag will be the aliasing blob.
     */
    setInMemoryRoot(): void;
    /**
     * @deprecated The functionality to get base GC details has been moved to summarizer node.
     */
    getBaseGCDetails(): Promise<IGarbageCollectionDetailsBase>;
    reSubmit(type: string, contents: any, localOpMetadata: unknown): void;
    rollback(type: string, contents: any, localOpMetadata: unknown): void;
    applyStashedOp(contents: any): Promise<unknown>;
    private verifyNotClosed;
    /**
     * Summarizer client should not have local changes. These changes can become part of the summary and can break
     * eventual consistency. For example, the next summary (say at ref seq# 100) may contain these changes whereas
     * other clients that are up-to-date till seq# 100 may not have them yet.
     */
    protected identifyLocalChangeInSummarizer(eventName: string, type?: string): void;
    getCreateChildSummarizerNodeFn(id: string, createParam: CreateChildSummarizerNodeParam): (summarizeInternal: SummarizeInternalFn, getGCDataFn: (fullGC?: boolean) => Promise<IGarbageCollectionData>) => ISummarizerNodeWithGC;
    deleteChildSummarizerNode(id: string): void;
    uploadBlob(blob: ArrayBufferLike, signal?: AbortSignal): Promise<IFluidHandleInternal<ArrayBufferLike>>;
}
/** @internal */
export declare class RemoteFluidDataStoreContext extends FluidDataStoreContext {
    private snapshotFetchRequired;
    private readonly runtime;
    private readonly blobContents;
    constructor(props: IRemoteFluidDataStoreContextProps);
    setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void;
    private readonly initialSnapshotDetailsP;
    getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
    /**
     * @see FluidDataStoreContext.getAttachSummary
     */
    getAttachSummary(): ISummaryTreeWithStats;
    /**
     * @see FluidDataStoreContext.getAttachGCData
     */
    getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData;
}
/**
 * Base class for detached & attached context classes
 * @internal
 */
export declare class LocalFluidDataStoreContextBase extends FluidDataStoreContext {
    private readonly snapshotTree;
    /**
     * @deprecated 0.16 Issue #1635, #3631
     */
    readonly createProps?: any;
    constructor(props: ILocalFluidDataStoreContextProps);
    setAttachState(attachState: AttachState.Attaching | AttachState.Attached): void;
    /**
     * @see FluidDataStoreContext.getAttachSummary
     */
    getAttachSummary(telemetryContext?: ITelemetryContext): ISummaryTreeWithStats;
    /**
     * @see FluidDataStoreContext.getAttachGCData
     */
    getAttachGCData(telemetryContext?: ITelemetryContext): IGarbageCollectionData;
    private readonly initialSnapshotDetailsP;
    getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
    /**
     * A context should only be marked as deleted when its a remote context.
     * Session Expiry at the runtime level should have closed the container creating the local data store context
     * before delete is even possible. Session Expiry is at 30 days, and sweep is done 36+ days later from the time
     * it was unreferenced. Thus the sweeping container should have loaded from a snapshot and thus creating a remote
     * context.
     */
    delete(): void;
}
/**
 * context implementation for "attached" data store runtime.
 * Various workflows (snapshot creation, requests) result in .realize() being called
 * on context, resulting in instantiation and attachment of runtime.
 * Runtime is created using data store factory that is associated with this context.
 * @internal
 */
export declare class LocalFluidDataStoreContext extends LocalFluidDataStoreContextBase {
    constructor(props: ILocalFluidDataStoreContextProps);
}
/**
 * Detached context. Data Store runtime will be attached to it by attachRuntime() call
 * Before attachment happens, this context is not associated with particular type of runtime
 * or factory, i.e. it's package path is undefined.
 * Attachment process provides all missing parts - package path, data store runtime, and data store factory
 */
export declare class LocalDetachedFluidDataStoreContext extends LocalFluidDataStoreContextBase implements IFluidDataStoreContextDetached {
    constructor(props: ILocalDetachedFluidDataStoreContextProps);
    private readonly channelToDataStoreFn;
    attachRuntime(registry: IProvideFluidDataStoreFactory, dataStoreChannel: IFluidDataStoreChannel): Promise<IDataStore>;
    getInitialSnapshotDetails(): Promise<ISnapshotDetails>;
}
//# sourceMappingURL=dataStoreContext.d.ts.map