/*!
 * 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 { InMemoryStoredSchemaRepository, JsonableTree, TreeStoredSchema } from "../core";
import { SharedTreeCore } from "../shared-tree-core";
import { DefaultEditBuilder, DefaultChangeset, SchemaEditor, TreeFieldSchema, TypedField } from "../feature-libraries";
import { JsonCompatibleReadOnly } from "../util";
import { type TypedTreeChannel } from "./typedTree";
import { InitializeAndSchematizeConfiguration } from "./schematizedTree";
import { ISharedTreeView, SharedTreeView } from "./sharedTreeView";
/**
 * 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, TypedTreeChannel {
    /**
     * Get view without schematizing.
     *
     * @deprecated This API will be removed as part of making views use view schema.
     */
    readonly view: ISharedTreeView;
    /**
     * 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;
    /**
     * Takes in a tree and returns a view of it that conforms to the view schema.
     * The returned view referees to and can edit the provided one: it is not a fork of it.
     * Updates the stored schema in the tree to match the provided one if requested by config and compatible.
     *
     * If the tree is uninitialized (has no nodes or schema at all),
     * it is initialized to the config's initial tree and the provided schema are stored.
     * This is done even if `AllowedUpdateType.None`.
     *
     * @remarks
     * Doing initialization here, regardless of `AllowedUpdateType`, allows a small API that is hard to use incorrectly.
     * Other approach tend to have leave easy to make mistakes.
     * For example, having a separate initialization function means apps can forget to call it, making an app that can only open existing document,
     * or call it unconditionally leaving an app that can only create new documents.
     * It also would require the schema to be passed into to separate places and could cause issues if they didn't match.
     * Since the initialization function couldn't return a typed tree, the type checking wouldn't help catch that.
     * Also, if an app manages to create a document, but the initialization fails to get persisted, an app that only calls the initialization function
     * on the create code-path (for example how a schematized factory might do it),
     * would leave the document in an unusable state which could not be repaired when it is reopened (by the same or other clients).
     * Additionally, once out of schema content adapters are properly supported (with lazy document updates),
     * this initialization could become just another out of schema content adapter: at tha point it clearly belong here in schematize.
     *
     * TODO:
     * - Implement schema-aware API for return type.
     * - Support adapters for handling out of schema data.
     */
    schematizeView<TRoot extends TreeFieldSchema>(config: InitializeAndSchematizeConfiguration<TRoot>): ISharedTreeView;
}
/**
 * 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: SharedTreeView;
    readonly storedSchema: SchemaEditor<InMemoryStoredSchemaRepository>;
    constructor(id: string, runtime: IFluidDataStoreRuntime, attributes: IChannelAttributes, optionsParam: SharedTreeOptions, telemetryContextPrefix: string);
    contentSnapshot(): SharedTreeContentSnapshot;
    schematizeView<TRoot extends TreeFieldSchema>(config: InitializeAndSchematizeConfiguration<TRoot>): SharedTreeView;
    schematize<TRoot extends TreeFieldSchema>(config: InitializeAndSchematizeConfiguration<TRoot>): TypedField<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;
}
/**
 * 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