/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { IChannelAttributes, IChannelFactory, IChannelServices, IChannelStorageService, IFluidDataStoreRuntime } from "@fluidframework/datastore-definitions";
import { ISequencedDocumentMessage } from "@fluidframework/protocol-definitions";
import { ISharedObject } from "@fluidframework/shared-object-base";
import { ICodecOptions } from "../codec";
import { FieldKey, InMemoryStoredSchemaRepository, JsonableTree, TreeStoredSchema } from "../core";
import { SharedTreeCore } from "../shared-tree-core";
import { DefaultEditBuilder, DefaultChangeset, SchemaEditor, TreeFieldSchema, TreeCompressionStrategy, TreeSchema, NodeKeyManager } from "../feature-libraries";
import { JsonCompatibleReadOnly } from "../util";
import { ITree, TreeConfiguration, ImplicitFieldSchema, TreeFieldFromImplicitField, TreeView } from "../class-tree";
import { InitializeAndSchematizeConfiguration } from "./schematizedTree";
import { TreeCheckout } from "./treeCheckout";
import { FlexTreeView, CheckoutFlexTreeView } from "./treeView";
/**
 * Copy of data from an {@link ISharedTree} at some point in time.
 * @remarks
 * This is unrelated to Fluids concept of "snapshots".
 * @alpha
 */
export interface SharedTreeContentSnapshot {
    /**
     * The schema stored in the document.
     *
     * @remarks
     * Edits to the schema can mutate the schema stored of the tree which took this snapshot (but this snapshot will remain the same)
     * This is mainly useful for debugging cases where schematize reports an incompatible view schema.
     */
    readonly schema: TreeStoredSchema;
    /**
     * All {@link TreeStatus#InDocument} content.
     */
    readonly tree: JsonableTree[];
}
/**
 * Collaboratively editable tree distributed data-structure,
 * powered by {@link @fluidframework/shared-object-base#ISharedObject}.
 *
 * See [the README](../../README.md) for details.
 * @alpha
 */
export interface ISharedTree extends ISharedObject, ITree {
    /**
     * Provides a copy of the current content of the tree.
     * This can be useful for inspecting the tree when no suitable view schema is available.
     * This is only intended for use in testing and exceptional code paths: it is not performant.
     *
     * This does not include everything that is included in a tree summary, since information about how to merge future edits is omitted.
     */
    contentSnapshot(): SharedTreeContentSnapshot;
    /**
     * Like {@link ITree.schematize}, but uses the flex-tree schema system and exposes the tree as a flex-tree.
     * @privateRemarks
     * This has to avoid its name colliding with `schematize`.
     * TODO: Either ITree and ISharedTree should be split into separate objects, the methods should be merged or a better convention for resolving such name conflicts should be selected.
     */
    schematizeInternal<TRoot extends TreeFieldSchema>(config: InitializeAndSchematizeConfiguration<TRoot>): FlexTreeView<TRoot>;
    /**
     * Like {@link ISharedTree.schematizeInternal}, but will never modify the document.
     *
     * @param schema - The view schema to use.
     * @param onSchemaIncompatible - A callback.
     * Invoked when the returned ISharedTreeView becomes invalid to use due to a change to the stored schema which makes it incompatible with the view schema.
     * Called at most once.
     * @returns a view compatible with the provided schema, or undefined if the stored schema is not compatible with the provided view schema.
     * If this becomes invalid to use due to a change in the stored schema, onSchemaIncompatible will be invoked.
     *
     * @privateRemarks
     * TODO:
     * Once views actually have a view schema, onSchemaIncompatible can become an event on the view (which ends its lifetime),
     * instead of a separate callback.
     */
    requireSchema<TRoot extends TreeFieldSchema>(schema: TreeSchema<TRoot>, onSchemaIncompatible: () => void): FlexTreeView<TRoot> | undefined;
}
/**
 * Shared tree, configured with a good set of indexes and field kinds which will maintain compatibility over time.
 *
 * TODO: detail compatibility requirements.
 */
export declare class SharedTree extends SharedTreeCore<DefaultEditBuilder, DefaultChangeset> implements ISharedTree {
    private readonly _events;
    readonly view: TreeCheckout;
    readonly storedSchema: SchemaEditor<InMemoryStoredSchemaRepository>;
    /**
     * Creating multiple editable tree contexts for the same branch, and thus with the same underlying AnchorSet does not work due to how TreeNode caching works.
     * This flag is used to detect if one already exists for the main branch and error if creating a second.
     * THis should catch most accidental violations of this restriction but there are still ways to create two conflicting contexts (for example calling constructing one manually).
     *
     * TODO:
     * 1. API docs need to reflect this limitation or the limitation has to be removed.
     */
    private hasView2;
    constructor(id: string, runtime: IFluidDataStoreRuntime, attributes: IChannelAttributes, optionsParam: SharedTreeOptions, telemetryContextPrefix: string);
    requireSchema<TRoot extends TreeFieldSchema>(schema: TreeSchema<TRoot>, onSchemaIncompatible: () => void, nodeKeyManager?: NodeKeyManager, nodeKeyFieldKey?: FieldKey): CheckoutFlexTreeView<TRoot> | undefined;
    contentSnapshot(): SharedTreeContentSnapshot;
    schematizeInternal<TRoot extends TreeFieldSchema>(config: InitializeAndSchematizeConfiguration<TRoot>, nodeKeyManager?: NodeKeyManager, nodeKeyFieldKey?: FieldKey): CheckoutFlexTreeView<TRoot>;
    schematize<TRoot extends ImplicitFieldSchema>(config: TreeConfiguration<TRoot>): TreeView<TreeFieldFromImplicitField<TRoot>>;
    /**
     * TODO: Shared tree needs a pattern for handling non-changeset operations.
     * Whatever pattern is adopted should probably also handle multiple versions of changeset operations.
     * A single top level enum listing all ops (including their different versions),
     * with at least fine grained enough detail to direct them to the correct subsystem would be a good approach.
     * The current use-case (with an op applying to a specific index) is a temporary hack,
     * and its not clear how it would fit into such a system if implemented in shared-tree-core:
     * maybe op dispatch is part of the shared-tree level?
     */
    protected processCore(message: ISequencedDocumentMessage, local: boolean, localOpMetadata: unknown): void;
    protected reSubmitCore(content: JsonCompatibleReadOnly, localOpMetadata: unknown): void;
    protected applyStashedOp(content: JsonCompatibleReadOnly): undefined;
    protected loadCore(services: IChannelStorageService): Promise<void>;
}
/**
 * @alpha
 */
export interface SharedTreeOptions extends Partial<ICodecOptions> {
    /**
     * The {@link ForestType} indicating which forest type should be created for the SharedTree.
     */
    forest?: ForestType;
    summaryEncodeType?: TreeCompressionStrategy;
}
/**
 * Used to distinguish between different forest types.
 * @alpha
 */
export declare enum ForestType {
    /**
     * The "ObjectForest" forest type.
     */
    Reference = 0,
    /**
     * The "ChunkedForest" forest type.
     */
    Optimized = 1
}
export declare const defaultSharedTreeOptions: Required<SharedTreeOptions>;
/**
 * A channel factory that creates {@link ISharedTree}s.
 * @alpha
 */
export declare class SharedTreeFactory implements IChannelFactory {
    private readonly options;
    readonly type: string;
    readonly attributes: IChannelAttributes;
    constructor(options?: SharedTreeOptions);
    load(runtime: IFluidDataStoreRuntime, id: string, services: IChannelServices, channelAttributes: Readonly<IChannelAttributes>): Promise<ISharedTree>;
    create(runtime: IFluidDataStoreRuntime, id: string): ISharedTree;
}
//# sourceMappingURL=sharedTree.d.ts.map