"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.TreeAlpha = void 0;
const internal_1 = require("@fluidframework/core-utils/internal");
const internal_2 = require("@fluidframework/id-compressor/internal");
const internal_3 = require("@fluidframework/telemetry-utils/internal");
const index_js_1 = require("../simple-tree/index.js");
const index_js_2 = require("../util/index.js");
const index_js_3 = require("../codec/index.js");
const index_js_4 = require("../feature-libraries/index.js");
const independentView_js_1 = require("./independentView.js");
const schematizingTreeView_js_1 = require("./schematizingTreeView.js");
/**
 * Extensions to {@link Tree} and {@link TreeBeta} which are not yet stable.
 * @sealed @alpha
 */
exports.TreeAlpha = {
    branch(node) {
        const kernel = (0, index_js_1.getKernel)(node);
        if (!kernel.isHydrated()) {
            return undefined;
        }
        const view = kernel.anchorNode.anchorSet.slots.get(schematizingTreeView_js_1.ViewSlot);
        (0, internal_1.assert)(view instanceof schematizingTreeView_js_1.SchematizingSimpleTreeView, 0xa5c /* Unexpected view implementation */);
        return view;
    },
    create: index_js_1.createFromInsertable,
    importConcise(schema, data) {
        return (0, index_js_1.createFromInsertable)(schema, data);
    },
    importVerbose(schema, data, options) {
        const config = {
            valueConverter: (input) => {
                return input;
            },
            ...options,
        };
        // Create a config which is standalone, and thus can be used without having to refer back to the schema.
        const schemalessConfig = (0, index_js_1.applySchemaToParserOptions)(schema, config);
        if (data === undefined) {
            const field = (0, index_js_1.normalizeFieldSchema)(schema);
            if (field.kind !== index_js_1.FieldKind.Optional) {
                throw new internal_3.UsageError("undefined provided for non-optional field.");
            }
            return undefined;
        }
        const cursor = (0, index_js_1.cursorFromVerbose)(data, schemalessConfig);
        return (0, index_js_1.createFromCursor)(schema, cursor);
    },
    exportConcise(node, options) {
        const config = {
            valueConverter(handle) {
                return handle;
            },
            ...options,
        };
        const cursor = borrowCursorFromTreeNodeOrValue(node);
        return (0, index_js_1.conciseFromCursor)(cursor, (0, index_js_1.tryGetSchema)(node) ?? (0, index_js_2.fail)("invalid input"), config);
    },
    exportVerbose(node, options) {
        const config = {
            valueConverter(handle) {
                return handle;
            },
            ...options,
        };
        const cursor = borrowCursorFromTreeNodeOrValue(node);
        return (0, index_js_1.verboseFromCursor)(cursor, (0, index_js_1.tryGetSchema)(node) ?? (0, index_js_2.fail)("invalid input"), config);
    },
    exportCompressed(node, options) {
        const schema = (0, index_js_1.tryGetSchema)(node) ?? (0, index_js_2.fail)("invalid input");
        const format = versionToFormat[options.oldestCompatibleClient];
        const codec = (0, index_js_4.makeFieldBatchCodec)({ jsonValidator: index_js_3.noopValidator }, format);
        const cursor = borrowFieldCursorFromTreeNodeOrValue(node);
        const batch = [cursor];
        // If none provided, create a compressor which will not compress anything.
        const idCompressor = options.idCompressor ?? (0, internal_2.createIdCompressor)();
        const context = {
            encodeType: index_js_4.TreeCompressionStrategy.Compressed,
            idCompressor,
            originatorId: idCompressor.localSessionId, // TODO: Why is this needed?
            schema: { schema: (0, index_js_1.toStoredSchema)(schema), policy: index_js_4.defaultSchemaPolicy },
        };
        const result = codec.encode(batch, context);
        return result;
    },
    importCompressed(schema, compressedData, options) {
        const content = {
            schema: (0, index_js_1.extractPersistedSchema)(schema),
            tree: compressedData,
            idCompressor: options.idCompressor ?? (0, internal_2.createIdCompressor)(),
        };
        const config = new index_js_1.TreeViewConfiguration({ schema });
        const view = (0, independentView_js_1.independentInitializedView)(config, options, content);
        return index_js_1.TreeBeta.clone(view.root);
    },
};
function borrowCursorFromTreeNodeOrValue(node) {
    if ((0, index_js_4.isTreeValue)(node)) {
        return (0, index_js_1.cursorFromInsertable)((0, index_js_1.tryGetSchema)(node) ?? (0, index_js_2.fail)("missing schema"), node);
    }
    const kernel = (0, index_js_1.getKernel)(node);
    const cursor = kernel.getOrCreateInnerNode().borrowCursor();
    return cursor;
}
function borrowFieldCursorFromTreeNodeOrValue(node) {
    const cursor = borrowCursorFromTreeNodeOrValue(node);
    // TODO: avoid copy
    const mapTree = (0, index_js_4.mapTreeFromCursor)(cursor);
    return (0, index_js_4.cursorForMapTreeField)([mapTree]);
}
const versionToFormat = {
    v2_0: 1,
    v2_1: 1,
    v2_2: 1,
    v2_3: 1,
};
//# sourceMappingURL=treeApiAlpha.js.map