"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.treeNodeApi = void 0;
const core_utils_1 = require("@fluidframework/core-utils");
const index_js_1 = require("../feature-libraries/index.js");
const flexNode_js_1 = require("./flexNode.js");
const proxies_js_1 = require("./proxies.js");
const schemaFactory_js_1 = require("./schemaFactory.js");
const toFlexSchema_js_1 = require("./toFlexSchema.js");
/**
 * The `Tree` object holds various functions for analyzing {@link TreeNode}s.
 */
exports.treeNodeApi = {
    parent: (node) => {
        const editNode = (0, flexNode_js_1.getFlexNode)(node).parentField.parent.parent;
        if (editNode === undefined) {
            return undefined;
        }
        const output = (0, proxies_js_1.getOrCreateNodeProxy)(editNode);
        (0, core_utils_1.assert)(!(0, index_js_1.isTreeValue)(output), 0x87f /* Parent can't be a leaf, so it should be a node not a value */);
        return output;
    },
    key: (node) => {
        const parentField = (0, flexNode_js_1.getFlexNode)(node).parentField;
        if (parentField.parent.schema.kind.multiplicity === index_js_1.Multiplicity.Sequence) {
            // The parent of `node` is an array node
            return parentField.index;
        }
        // The parent of `node` is an object, a map, or undefined (and therefore `node` is a root/detached node).
        return parentField.parent.key;
    },
    on: (node, eventName, listener) => {
        return (0, flexNode_js_1.getFlexNode)(node).on(eventName, listener);
    },
    status: (node) => {
        return (0, flexNode_js_1.getFlexNode)(node, true).treeStatus();
    },
    is: (value, schema) => {
        const flexSchema = (0, toFlexSchema_js_1.getFlexSchema)(schema);
        if ((0, index_js_1.isTreeValue)(value)) {
            return (flexSchema instanceof index_js_1.LeafNodeSchema && (0, index_js_1.valueSchemaAllows)(flexSchema.info, value));
        }
        return (0, flexNode_js_1.tryGetFlexNode)(value)?.is(flexSchema) ?? false;
    },
    schema(node) {
        if ((0, index_js_1.isTreeValue)(node)) {
            return (0, schemaFactory_js_1.schemaFromValue)(node);
        }
        return (0, proxies_js_1.getClassSchema)((0, flexNode_js_1.getFlexNode)(node).schema);
    },
};
//# sourceMappingURL=treeApi.js.map