/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { assert } from "@fluidframework/core-utils";
import { LeafNodeSchema, Multiplicity, isTreeValue, valueSchemaAllows, } from "../feature-libraries/index.js";
import { getFlexNode, tryGetFlexNode } from "./flexNode.js";
import { getClassSchema, getOrCreateNodeProxy } from "./proxies.js";
import { schemaFromValue } from "./schemaFactory.js";
import { getFlexSchema } from "./toFlexSchema.js";
/**
 * The `Tree` object holds various functions for analyzing {@link TreeNode}s.
 */
export const treeNodeApi = {
    parent: (node) => {
        const editNode = getFlexNode(node).parentField.parent.parent;
        if (editNode === undefined) {
            return undefined;
        }
        const output = getOrCreateNodeProxy(editNode);
        assert(!isTreeValue(output), 0x87f /* Parent can't be a leaf, so it should be a node not a value */);
        return output;
    },
    key: (node) => {
        const parentField = getFlexNode(node).parentField;
        if (parentField.parent.schema.kind.multiplicity === 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 getFlexNode(node).on(eventName, listener);
    },
    status: (node) => {
        return getFlexNode(node, true).treeStatus();
    },
    is: (value, schema) => {
        const flexSchema = getFlexSchema(schema);
        if (isTreeValue(value)) {
            return (flexSchema instanceof LeafNodeSchema && valueSchemaAllows(flexSchema.info, value));
        }
        return tryGetFlexNode(value)?.is(flexSchema) ?? false;
    },
    schema(node) {
        if (isTreeValue(node)) {
            return schemaFromValue(node);
        }
        return getClassSchema(getFlexNode(node).schema);
    },
};
//# sourceMappingURL=treeApi.js.map