"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.TreeBeta = exports.exportConcise = exports.importConcise = exports.borrowCursorFromTreeNodeOrValue = void 0;
const index_js_1 = require("../../feature-libraries/index.js");
const index_js_2 = require("../../util/index.js");
const index_js_3 = require("../core/index.js");
const createContext_js_1 = require("../createContext.js");
const unhydratedFlexTreeFromInsertable_js_1 = require("../unhydratedFlexTreeFromInsertable.js");
const conciseTree_js_1 = require("./conciseTree.js");
const create_js_1 = require("./create.js");
const treeNodeApi_js_1 = require("./treeNodeApi.js");
const verboseTree_js_1 = require("./verboseTree.js");
/**
 * Borrow a cursor from a node.
 * @remarks
 * The cursor must be put back to its original location before the node is used again.
 */
function borrowCursorFromTreeNodeOrValue(node) {
    if ((0, index_js_1.isTreeValue)(node)) {
        return (0, verboseTree_js_1.cursorFromVerbose)(node, {});
    }
    const kernel = (0, index_js_3.getKernel)(node);
    const cursor = kernel.getInnerNode().borrowCursor();
    return cursor;
}
exports.borrowCursorFromTreeNodeOrValue = borrowCursorFromTreeNodeOrValue;
function importConcise(schema, data) {
    // Create the tree content from insertable data
    const mapTree = (0, unhydratedFlexTreeFromInsertable_js_1.unhydratedFlexTreeFromInsertable)(data, schema);
    const result = mapTree === undefined ? undefined : (0, index_js_3.getOrCreateNodeFromInnerNode)(mapTree);
    return result;
}
exports.importConcise = importConcise;
function exportConcise(node, options) {
    if (!(0, index_js_3.isTreeNode)(node)) {
        return node;
    }
    const config = { ...options };
    const kernel = (0, index_js_3.getKernel)(node);
    const cursor = borrowCursorFromTreeNodeOrValue(node);
    return (0, conciseTree_js_1.conciseFromCursor)(cursor, kernel.context, config);
}
exports.exportConcise = exportConcise;
/**
 * Extensions to {@link (Tree:variable)} which are not yet stable.
 * @see {@link (TreeBeta:interface)}.
 * @beta
 */
exports.TreeBeta = {
    on(node, eventName, listener) {
        return treeNodeApi_js_1.treeNodeApi.on(node, eventName, listener);
    },
    importConcise,
    exportConcise,
    clone(node) {
        // The only non-TreeNode cases are {@link TreeLeafValue} and `undefined` (for an empty optional field) which can be returned as is.
        if (!(0, index_js_3.isTreeNode)(node)) {
            return node;
        }
        const kernel = (0, index_js_3.getKernel)(node);
        const cursor = kernel.getInnerNode().borrowCursor();
        // To handle when the node transitively contains unknown optional fields,
        // derive the context from the source node's stored schema which has stored schema for any such fields and their contents.
        const flexContext = new index_js_3.UnhydratedContext(index_js_1.defaultSchemaPolicy, kernel.context.flexContext.schema);
        const context = new index_js_3.Context(flexContext, (0, createContext_js_1.getUnhydratedContext)(kernel.schema).schema);
        const fieldSchema = {
            kind: index_js_1.FieldKinds.required.identifier,
            types: new Set([(0, index_js_2.brand)(kernel.schema.identifier)]),
            persistedMetadata: undefined,
        };
        return (0, create_js_1.createFromCursor)(kernel.schema, cursor, fieldSchema, context);
    },
    create(schema, data) {
        const mapTree = (0, unhydratedFlexTreeFromInsertable_js_1.unhydratedFlexTreeFromInsertable)(data, schema);
        const result = mapTree === undefined ? undefined : (0, index_js_3.getOrCreateNodeFromInnerNode)(mapTree);
        return result;
    },
};
//# sourceMappingURL=treeBeta.js.map