/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { IFluidHandle } from "@fluidframework/core-interfaces";
import { type FieldKey, type ITreeCursor, type ITreeCursorSynchronous } from "../../core/index.js";
import type { TreeLeafValue, ImplicitFieldSchema, ImplicitAllowedTypes } from "../schemaTypes.js";
import { type EncodeOptions } from "./customTree.js";
/**
 * Verbose encoding of a {@link TreeNode} or {@link TreeLeafValue}.
 * @remarks
 * This is verbose meaning that every {@link TreeNode} is a {@link VerboseTreeNode}.
 * Any IFluidHandle values have been replaced by `THandle`.
 * @privateRemarks
 * This can store all possible simple trees,
 * but it can not store all possible trees representable by our internal representations like FlexTree and JsonableTree.
 * @alpha
 */
export type VerboseTree<THandle = IFluidHandle> = VerboseTreeNode<THandle> | Exclude<TreeLeafValue, IFluidHandle> | THandle;
/**
 * Verbose encoding of a {@link TreeNode}.
 * @remarks
 * This is verbose meaning that every {@link TreeNode} has an explicit `type` property, and `fields`.
 * This allowed VerboseTreeNode to be unambiguous regarding which type each node is without relying on symbols or hidden state.
 *
 * Any IFluidHandle values have been replaced by `THandle`. If the `THandle` is JSON compatible, then this type is JSON compatible as well.
 *
 * @privateRemarks
 * This type is only used for data which is copied into and out of the tree.
 * When being copied out, its fine to have the data be mutable since its a copy.
 *
 * When being copied in, we don't need to mutate, so we could use a readonly variant of this type.
 * however the copy in case (createFromVerbose) probably isn't harmed much by just reusing this type as is,
 * since if the caller has immutable data, TypeScript doesn't prevent assigning immutable data to a mutable type anyway.
 * Also relaxing the input methods to take readonly data would be a non-breaking change so it can be done later if desired.
 *
 * This format is simple-tree specialized alternative to {@link JsonableTree}.
 * This format allows for all simple-tree compatible trees to be represented.
 *
 * Unlike `JsonableTree`, leaf nodes are not boxed into node objects, and instead have their schema inferred from the value.
 * Additionally, sequence fields can only occur on a node that has a single sequence field (with the empty key)
 * replicating the behavior of simple-tree ArrayNodes.
 * @alpha
 */
export interface VerboseTreeNode<THandle = IFluidHandle> {
    /**
     * The meaning of this node.
     * Provides contexts/semantics for this node and its content.
     * @remarks
     * Typically used to associate a node with metadata (including a schema) and source code (types, behaviors, etc).
     * When used with this package's schema system, it will be the {@link TreeNodeSchemaCore.identifier}.
     */
    type: string;
    /**
     * Content of this node.
     * For array nodes, an array of children.
     * For map and object nodes, an object which children under keys.
     * @remarks
     * For object nodes, the keys could be either the stored keys, or the property keys depending on usage.
     */
    fields: VerboseTree<THandle>[] | {
        [key: string]: VerboseTree<THandle>;
    };
}
/**
 * Options for how to interpret a `VerboseTree<TCustom>` when schema information is available.
 * @alpha
 */
export interface ParseOptions<TCustom> {
    /**
     * Fixup custom input formats.
     * @remarks
     * Main usage is to handle IFluidHandles.
     * When targeting JSON compatibility,
     * this may be by throwing an error or including a placeholder.
     * Since IFluidHandles are special references to FLuid data which is garbage collected when not referenced by the container for long enough,
     * any scheme for encoding handles for storage outside the container (or in formats the container does not understand) is unreliable.
     */
    valueConverter(data: VerboseTree<TCustom>): TreeLeafValue | VerboseTreeNode<TCustom>;
    /**
     * If true, interpret the input keys of object nodes as stored keys.
     * If false, interpret them as property keys.
     * @defaultValue false.
     */
    readonly useStoredKeys?: boolean;
}
/**
 * Options for how to interpret a `VerboseTree<TCustom>` without relying on schema.
 */
export interface SchemalessParseOptions<TCustom> {
    /**
     * Fixup custom input formats.
     * @remarks
     * See note on {@link ParseOptions.valueConverter}.
     */
    valueConverter(data: VerboseTree<TCustom>): TreeLeafValue | VerboseTreeNode<TCustom>;
    /**
     * Converts stored keys into whatever key the tree is using in its encoding.
     */
    keyConverter?: {
        parse(type: string, inputKey: string): FieldKey;
        encode(type: string, key: FieldKey): string;
    };
}
/**
 * Use info from `schema` to convert `options` to {@link SchemalessParseOptions}.
 */
export declare function applySchemaToParserOptions<TCustom>(schema: ImplicitFieldSchema, options: ParseOptions<TCustom>): SchemalessParseOptions<TCustom>;
/**
 * Used to read a VerboseTree as a node cursor.
 *
 * @returns an {@link ITreeCursorSynchronous} for a single node in nodes mode.
 */
export declare function cursorFromVerbose<TCustom>(data: VerboseTree<TCustom>, options: SchemalessParseOptions<TCustom>): ITreeCursorSynchronous;
/**
 * Used to read a VerboseTree[] as a field cursor.
 *
 * @returns an {@link ITreeCursorSynchronous} for a single field in fields mode.
 */
export declare function fieldCursorFromVerbose<TCustom>(data: VerboseTree<TCustom>[], options: SchemalessParseOptions<TCustom>): ITreeCursorSynchronous;
/**
 * Used to read a node cursor as a VerboseTree.
 */
export declare function verboseFromCursor<TCustom>(reader: ITreeCursor, rootSchema: ImplicitAllowedTypes, options: EncodeOptions<TCustom>): VerboseTree<TCustom>;
//# sourceMappingURL=verboseTree.d.ts.map