/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import type { Listenable } from "@fluidframework/core-interfaces/internal";
import type { IIdCompressor } from "@fluidframework/id-compressor";
import { type ITelemetryLoggerExt } from "@fluidframework/telemetry-utils/internal";
import { type CodecWriteOptions } from "../codec/index.js";
import { type Anchor, type AnchorLocator, type AnchorNode, type AnchorSetRootEvents, type ChangeFamily, type DetachedFieldIndex, type IEditableForest, type IForestSubscription, type JsonableTree, type RevisionTag, type RevisionTagCodec, type TreeStoredSchema, TreeStoredSchemaRepository, type TreeStoredSchemaSubscription, type RevertibleAlphaFactory, type GraphCommit, type ChangeMetadata, type ReadOnlyDetachedFieldIndex, type TaggedChange } from "../core/index.js";
import { type FieldBatchCodec, type TreeCompressionStrategy } from "../feature-libraries/index.js";
import { SharedTreeBranch, type SharedTreeBranchChange, type Transactor } from "../shared-tree-core/index.js";
import { type ImplicitFieldSchema, type ReadSchema, type TreeView, type TreeViewConfiguration, type UnsafeUnknownSchema, type ViewableTree, type TreeBranch, type TreeBranchAlpha, type VerboseTree, type VoidTransactionCallbackStatus, type TransactionCallbackStatus, type TransactionResult, type TransactionResultExt, type RunTransactionParams, type TransactionConstraintAlpha, type TreeViewAlpha } from "../simple-tree/index.js";
import { Breakable, disposeSymbol, type JsonCompatibleReadOnly, type WithBreakable } from "../util/index.js";
import { SchematizingSimpleTreeView } from "./schematizingTreeView.js";
import type { SharedTreeChange } from "./sharedTreeChangeTypes.js";
import type { ISharedTreeEditor, SharedTreeEditBuilder } from "./sharedTreeEditBuilder.js";
/**
 * Events for {@link ITreeCheckout}.
 */
export interface CheckoutEvents {
    /**
     * The view is currently in a consistent state, but a batch of changes is about to be processed.
     * @remarks Once this event fires, it is not safe to access the FlexTree, Forest and AnchorSet again until the corresponding {@link CheckoutEvents.afterBatch} fires.
     * Every call to `beforeBatch` will be followed by a corresponding call to `afterBatch` (before any more calls to `beforeBatch`).
     * @param change - The {@link SharedTreeBranchChange | change} to the checkout's active branch that is about to be processed.
     * May be empty if the changes were produced by e.g. a rebase or the initial loading of the document.
     */
    beforeBatch(change: SharedTreeBranchChange<SharedTreeChange>): void;
    /**
     * A batch of changes has finished processing and the view is in a consistent state.
     * @remarks It is once again safe to access the FlexTree, Forest and AnchorSet.
     *
     * While every call to `beforeBatch` will be followed by a corresponding call to `afterBatch`, the converse is not true.
     * This event may be fired without a preceding `beforeBatch` event if the checkout's branch and forest were directly updated via e.g. a summary load rather than via normal application of changes.
     * @remarks
     * This is mainly useful for knowing when to do followup work scheduled during events from Anchors.
     */
    afterBatch(): void;
    /**
     * Fired when a change is made to the branch. Includes data about the change that is made which listeners
     * can use to filter on changes they care about e.g. local vs remote changes.
     *
     * @param data - information about the change
     */
    changed(data: ChangeMetadata, getRevertible?: RevertibleAlphaFactory): void;
    /**
     * Fired when a new branch is created from this checkout.
     */
    fork(branch: ITreeCheckout): void;
    /**
     * Fired when the checkout is disposed.
     */
    dispose(): void;
}
/**
 * Provides a means for interacting with a SharedTree.
 * This includes reading data from the tree and running transactions to mutate the tree.
 * @remarks This interface should not have any implementations other than those provided by the SharedTree package libraries.
 * @privateRemarks
 * API for interacting with a {@link SharedTreeBranch}.
 * Implementations of this interface must implement the {@link branchKey} property.
 */
export interface ITreeCheckout extends TreeBranchAlpha, AnchorLocator, ViewableTree, WithBreakable {
    /**
     * Read and Write access for schema stored in the document.
     *
     * These APIs are temporary and will be replaced with different abstractions (View Schema based) in a different place later.
     *
     * TODO:
     * Editing of this should be moved into transactions with the rest of tree editing to they can be intermixed.
     * This will be done after the relations between views, branches and Indexes are figured out.
     *
     * TODO:
     * Public APIs for dealing with schema should be in terms of View Schema, and schema update policies.
     * The actual stored schema should be hidden (or ar least not be the most prominent way to interact with schema).
     *
     * TODO:
     * Something should ensure the document contents are always in schema.
     */
    readonly storedSchema: TreeStoredSchemaSubscription;
    /**
     * Current contents.
     * Updated by edits (local and remote).
     * Use `editor` to create a local edit.
     */
    readonly forest: IForestSubscription;
    /**
     * Used to edit the state of the tree. Edits will be immediately applied locally to the tree.
     * If there is no transaction currently ongoing, then the edits will be submitted to Fluid immediately as well.
     */
    readonly editor: ISharedTreeEditor;
    /**
     * A collection of functions for managing transactions.
     */
    readonly transaction: Transactor;
    fork(): ITreeCheckout;
    /**
     * Replaces all schema with the provided schema.
     * Can over-write preexisting schema, and removes unmentioned schema.
     *
     * @param newSchema - The new schema to replace the existing schema.
     * @param allowNonSupersetSchema - Whether to allow non-superset schemas.
     * Defaults to false.
     * If false, an assert will be thrown if the new schema does not permit all possible documents which were permitted under the old schema.
     */
    updateSchema(newSchema: TreeStoredSchema, allowNonSupersetSchema?: true): void;
    /**
     * Events about this view.
     */
    readonly events: Listenable<CheckoutEvents>;
    /**
     * Events about the root of the tree in this view.
     */
    readonly rootEvents: Listenable<AnchorSetRootEvents>;
    /**
     * Returns a JsonableTree for each tree that was removed from (and not restored to) the document.
     * This list is guaranteed to contain all nodes that are recoverable through undo/redo on this checkout.
     * The list may also contain additional nodes.
     *
     * This is only intended for use in testing and exceptional code paths: it is not performant.
     */
    getRemovedRoots(): [string | number | undefined, number, JsonableTree][];
}
/**
 * Creates a {@link TreeCheckout}.
 * @param args - an object containing optional components that will be used to build the view.
 * Any components not provided will be created by default.
 * @remarks This does not create a {@link SharedTree}, but rather a view with the minimal state
 * and functionality required to implement {@link ITreeCheckout}.
 */
export declare function createTreeCheckout(idCompressor: IIdCompressor, mintRevisionTag: () => RevisionTag, revisionTagCodec: RevisionTagCodec, args?: {
    branch?: SharedTreeBranch<SharedTreeEditBuilder, SharedTreeChange>;
    changeFamily?: ChangeFamily<SharedTreeEditBuilder, SharedTreeChange>;
    schema?: TreeStoredSchemaRepository;
    forest?: IEditableForest;
    fieldBatchCodec?: FieldBatchCodec;
    removedRoots?: DetachedFieldIndex;
    chunkCompressionStrategy?: TreeCompressionStrategy;
    logger?: ITelemetryLoggerExt;
    breaker?: Breakable;
    disposeForksAfterTransaction?: boolean;
    codecOptions?: Partial<CodecWriteOptions>;
}): TreeCheckout;
/**
 * Metrics derived from a revert operation.
 *
 * @see {@link TreeCheckout.revertRevertible}.
 */
export interface RevertMetrics {
    /**
     * The age of the revertible commit relative to the head of the branch to which the reversion will be applied.
     */
    readonly age: number;
}
/**
 * Adds constraints to a `checkout`'s pending transaction.
 *
 * @param checkout - The checkout whose transaction will have the constraints added to it.
 * @param constraintsOnRevert - If true, use {@link ISharedTreeEditor.addNodeExistsConstraintOnRevert}.
 * @param constraints - The constraints to add to the transaction.
 *
 * @see {@link RunTransactionParams.preconditions}.
 */
export declare function addConstraintsToTransaction(checkout: ITreeCheckout, constraintsOnRevert: boolean, constraints?: readonly TransactionConstraintAlpha[]): void;
/**
 * Throws if the given {@link TransactionConstraintAlpha | transaction constraint} is not currently satisfied.
 */
export declare function assertValidConstraint(constraint: TransactionConstraintAlpha, onRevert: boolean): void;
/**
 * An implementation of {@link ITreeCheckout}.
 */
export declare class TreeCheckout implements ITreeCheckout {
    #private;
    /** True if and only if this checkout is for a branch which is persisted and shared with other clients. */
    readonly isSharedBranch: boolean;
    private readonly changeFamily;
    readonly storedSchema: TreeStoredSchemaRepository;
    readonly forest: IEditableForest;
    private readonly mintRevisionTag;
    private readonly revisionTagCodec;
    private readonly idCompressor;
    private readonly _removedRoots;
    /** Optional logger for telemetry. */
    private readonly logger?;
    readonly breaker: Breakable;
    readonly disposeForksAfterTransaction: boolean;
    disposed: boolean;
    private editLock;
    /**
     * Root of the mutable label tree tracking transaction nesting.
     *
     * @remarks
     * The label tree is always isomorphic to the actual transaction tree — every transaction
     * (whether labeled or not) gets its own node. To find the "current" (deepest open) node,
     * walk down the right side of the tree, stopping at {@link TreeCheckout.mostRecentlyClosedLabelNode}.
     *
     * Cleared by {@link TreeCheckout.runWithTransactionLabel} after the commit event is emitted.
     */
    private labelTreeNode;
    /**
     * Points to the most recently closed (committed) label node.
     * Used by {@link TreeCheckout.currentLabelNode} to stop descending past committed nodes.
     */
    private mostRecentlyClosedLabelNode;
    private readonly views;
    /**
     * Set of revertibles maintained for automatic disposal
     */
    private readonly revertibles;
    /**
     * Each branch's head commit corresponds to a revertible commit.
     * Maintaining a whole branch ensures the commit graph is not pruned in a way that would prevent the commit from
     * being reverted.
     */
    private readonly revertibleCommitBranches;
    /**
     * The name of the telemetry event logged for calls to {@link TreeCheckout.revertRevertible}.
     * @privateRemarks Exposed for testing purposes.
     */
    static readonly revertTelemetryEventName = "RevertRevertible";
    events: Listenable<CheckoutEvents>;
    constructor(branch: SharedTreeBranch<SharedTreeEditBuilder, SharedTreeChange>, 
    /** True if and only if this checkout is for a branch which is persisted and shared with other clients. */
    isSharedBranch: boolean, changeFamily: ChangeFamily<SharedTreeEditBuilder, SharedTreeChange>, storedSchema: TreeStoredSchemaRepository, forest: IEditableForest, mintRevisionTag: () => RevisionTag, revisionTagCodec: RevisionTagCodec, idCompressor: IIdCompressor, _removedRoots?: DetachedFieldIndex, 
    /** Optional logger for telemetry. */
    logger?: import("@fluidframework/telemetry-utils/internal").TelemetryLoggerExt | undefined, breaker?: Breakable, disposeForksAfterTransaction?: boolean);
    /**
     * Pushes a new label node for a transaction nesting level.
     *
     * @param label - The label for this transaction level.
     *
     * @remarks
     * Called at the start of each transaction (including nested ones).
     * Creates a new {@link LabelTree} node as a child of the current deepest node (if any),
     * or as the root if this is the outermost transaction.
     */
    pushLabelFrame(label: unknown): void;
    /**
     * Returns the deepest open node on the right side of the label tree, which corresponds
     * to the current (most recently pushed, not yet committed or aborted) transaction.
     * Returns `undefined` when {@link TreeCheckout.labelTreeNode} is not set.
     */
    private currentLabelNode;
    /**
     * Pops the current label frame from the label tree.
     * @param aborted - If true, the node is removed from the tree (transaction was aborted).
     * If false, the node is kept in the tree but marked as closed (transaction was committed).
     */
    popLabelFrame(aborted: boolean): void;
    /**
     * Helper method for {@link SchematizingSimpleTreeView.runTransaction} to properly clear transaction labels once the function completes.
     *
     * @remarks
     * The label is stored during the execution of the function and will be included in the {@link ChangeMetadata} of the transaction.
     *
     * Labels supplied to nested transactions are ignored - only the outermost transaction label is ever used.
     *
     * @param fn - The function to execute. It receives the user provided transaction label as an optional parameter.
     * @param label - The label to associate with the outermost transaction.
     * @returns The result of executing `fn`.
     */
    runWithTransactionLabel<TLabel, TResult>(fn: (label?: TLabel) => TResult, label: TLabel | undefined): TResult;
    get removedRoots(): ReadOnlyDetachedFieldIndex;
    private registerForBranchEvents;
    private unregisterFromBranchEvents;
    private createTransactionStack;
    exportVerbose(): VerboseTree | undefined;
    private readonly onAfterBranchChange;
    private readonly onAfterChange;
    /**
     * Applies the given serialized change (as was produced via a `"changed"` event of another checkout) to this checkout.
     */
    applySerializedChange(serializedChange: JsonCompatibleReadOnly): void;
    applyChange(change: JsonCompatibleReadOnly): void;
    isBranch(): this is TreeBranchAlpha;
    hasRootSchema<TSchema extends ImplicitFieldSchema>(_schema: TSchema): this is TreeViewAlpha<TSchema>;
    runTransaction<TSuccessValue, TFailureValue>(transaction: () => TransactionCallbackStatus<TSuccessValue, TFailureValue>, params?: RunTransactionParams): TransactionResultExt<TSuccessValue, TFailureValue>;
    runTransaction(transaction: () => VoidTransactionCallbackStatus | void, params?: RunTransactionParams): TransactionResult;
    runTransactionAsync<TSuccessValue, TFailureValue>(transaction: () => Promise<TransactionCallbackStatus<TSuccessValue, TFailureValue>>, params?: RunTransactionParams): Promise<TransactionResultExt<TSuccessValue, TFailureValue>>;
    runTransactionAsync(transaction: () => Promise<VoidTransactionCallbackStatus | void>, params?: RunTransactionParams): Promise<TransactionResult>;
    private mountTransaction;
    private unmountTransaction;
    private applyInternalChange;
    private readonly onAncestryTrimmed;
    private withCombinedVisitor;
    private checkNotDisposed;
    /**
     * Creates a {@link RevertibleAlpha} object that can undo a specific change in the tree's history.
     * Revision must exist in the given {@link TreeCheckout}'s branch.
     *
     * @param revision - The revision tag identifying the change to be made revertible.
     * @param kind - The {@link CommitKind} that produced this revertible (e.g., Default, Undo, Redo).
     * @param checkout - The {@link TreeCheckout} instance this revertible belongs to.
     * @param onRevertibleDisposed - Callback function that will be called when the revertible is disposed.
     * @returns A {@link RevertibleAlpha} object.
     */
    private createRevertible;
    viewWith<TRoot extends ImplicitFieldSchema | UnsafeUnknownSchema>(config: TreeViewConfiguration<ReadSchema<TRoot>>): SchematizingSimpleTreeView<TRoot>;
    viewWith<TRoot extends ImplicitFieldSchema>(config: TreeViewConfiguration<TRoot>): TreeView<TRoot>;
    get rootEvents(): Listenable<AnchorSetRootEvents>;
    get editor(): ISharedTreeEditor;
    locate(anchor: Anchor): AnchorNode | undefined;
    get transaction(): Transactor;
    fork(): TreeCheckout;
    switchBranch(branch: SharedTreeBranch<SharedTreeEditBuilder, SharedTreeChange>): void;
    private rebase;
    rebaseOnto(branch: TreeBranch): void;
    merge(branch: TreeBranch): void;
    merge(branch: TreeBranch, disposeMerged: boolean): void;
    updateSchema(newSchema: TreeStoredSchema, allowNonSupersetSchema?: true): void;
    dispose(): void;
    [disposeSymbol](): void;
    getRemovedRoots(): [string | number | undefined, number, JsonableTree][];
    /**
     * This must be called on the root/main checkout after loading from a summary.
     * @remarks This pattern is necessary because the EditManager skips the normal process of applying commits to branches when loading a summary.
     * Instead, it simply {@link SharedTreeBranch#setHead | mutates} the branches directly which does not propagate the typical events throughout the rest of the system.
     */
    load(): void;
    private purgeRevertibles;
    private disposeRevertible;
    private revertRevertible;
    private assertNoUntrackedRoots;
    /**
     * `true` iff the given branch change event is due to a remote change
     */
    private isRemoteChangeEvent;
    /**
     * Registers a function to be called when the given commit is validated.
     * @remarks A commit is validated by the checkout after it has been applied to the checkout's state (e.g. it has an effect on the forest).
     * If the commit applies successfully (i.e. it does not raise any unexpected errors), the commit is considered valid and the registered function is called.
     * If the commit does not apply successfully (because it causes an unexpected error), the function is not called (and the checkout will left in an error state).
     *
     * If the commit has already been validated when this function is called, the function is called immediately and this function returns `true`.
     * Otherwise, the function is registered to be called later and this function returns `false`.
     */
    onCommitValid(commit: GraphCommit<SharedTreeChange>, fn: (commit: GraphCommit<SharedTreeChange>) => void): boolean;
    /** Mark the given commit as "validated" according to the contract of {@link onCommitValid}(). */
    private validateCommit;
    /**
     * Statistics about enrichment operations performed by this checkout.
     * Used for testing. May be used for telemetry in the future.
     * The performance cost of maintaining this information is negligible.
     */
    private readonly enrichmentStats;
    resetEnrichmentStats(): void;
    getEnrichmentStats(): {
        batches: number;
        diffs: number;
        commitsEnriched: number;
        refreshers: number;
        forks: number;
        applied: number;
    };
    enrich(context: GraphCommit<SharedTreeChange>, changes: readonly TaggedChange<SharedTreeChange>[]): SharedTreeChange[];
    get mainBranch(): SharedTreeBranch<SharedTreeEditBuilder, SharedTreeChange>;
}
//# sourceMappingURL=treeCheckout.d.ts.map