/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { assert } from "@fluidframework/core-utils/internal";
import { Context, } from "../feature-libraries/index.js";
import { tryDisposeTreeNode } from "../simple-tree/index.js";
import { disposeSymbol } from "../util/index.js";
/**
 * An editable view of a (version control style) branch of a shared tree.
 * @remarks
 * Does not depend on stored schema, and thus can live across schema changes.
 * @privateRemarks
 * This has no state beyond the context, so it likely should be replaced with just the context.
 */
export class CheckoutFlexTreeView {
    /**
     * Get a view of the tree content using the flex-tree API.
     */
    get flexTree() {
        return this.context.root;
    }
    constructor(
    /**
     * Access non-view schema specific aspects of this branch.
     *
     * @remarks
     * This is a non-owning reference: disposing of this view does not impact the branch.
     */
    checkout, schema, nodeKeyManager, onDispose) {
        this.checkout = checkout;
        this.schema = schema;
        this.nodeKeyManager = nodeKeyManager;
        this.onDispose = onDispose;
        this.disposed = false;
        this.context = new Context(schema, this.checkout, nodeKeyManager);
        contextToTreeViewMap.set(this.context, this);
    }
    [disposeSymbol]() {
        assert(!this.disposed, 0xb80 /* Double disposed */);
        this.disposed = true;
        for (const anchorNode of this.checkout.forest.anchors) {
            tryDisposeTreeNode(anchorNode);
        }
        this.context[disposeSymbol]();
        this.onDispose?.();
    }
    /**
     * Spawn a new view which is based off of the current state of this view.
     * Any mutations of the new view will not apply to this view until the new view is merged back into this view via `merge()`.
     */
    fork() {
        assert(!this.disposed, 0xb81 /* disposed */);
        const branch = this.checkout.branch();
        return new CheckoutFlexTreeView(branch, this.schema, this.nodeKeyManager);
    }
}
/**
 * Maps the context of every {@link CheckoutFlexTreeView} to the view.
 * In practice, this allows the view or checkout to be obtained from a flex node by first getting the context from the flex node and then using this map.
 */
const contextToTreeViewMap = new WeakMap();
/**
 * Retrieve the {@link CheckoutFlexTreeView | view} for the given {@link FlexTreeHydratedContext | context}.
 * @remarks Every {@link CheckoutFlexTreeView} is associated with its context upon creation.
 */
export function getCheckoutFlexTreeView(context) {
    const view = contextToTreeViewMap.get(context);
    assert(view !== undefined, 0xa41 /* Expected view to be registered for context */);
    return view;
}
//# sourceMappingURL=checkoutFlexTreeView.js.map