"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.isTreeValue = exports.assertAllowedValue = exports.isFluidHandle = exports.valueSchemaAllows = exports.allowsValue = void 0;
const internal_1 = require("@fluidframework/core-utils/internal");
const index_js_1 = require("../core/index.js");
function allowsValue(schema, nodeValue) {
    if (schema === undefined) {
        return nodeValue === undefined;
    }
    return valueSchemaAllows(schema, nodeValue);
}
exports.allowsValue = allowsValue;
function valueSchemaAllows(schema, nodeValue) {
    switch (schema) {
        case index_js_1.ValueSchema.String:
            return typeof nodeValue === "string";
        case index_js_1.ValueSchema.Number:
            return typeof nodeValue === "number";
        case index_js_1.ValueSchema.Boolean:
            return typeof nodeValue === "boolean";
        case index_js_1.ValueSchema.FluidHandle:
            return isFluidHandle(nodeValue);
        case index_js_1.ValueSchema.Null:
            return nodeValue === null;
        default:
            (0, internal_1.unreachableCase)(schema);
    }
}
exports.valueSchemaAllows = valueSchemaAllows;
// TODO: replace test in FluidSerializer.encodeValue with this.
function isFluidHandle(value) {
    if (typeof value !== "object" || value === null || !("IFluidHandle" in value)) {
        return false;
    }
    const handle = value.IFluidHandle;
    // Regular Json compatible data can have fields named "IFluidHandle" (especially if field names come from user data).
    // Separate this case from actual Fluid handles by checking for a circular reference: Json data can't have this circular reference so it is a safe way to detect IFluidHandles.
    const isHandle = handle === value;
    // Since the requirement for this reference to be cyclic isn't particularly clear in the interface (typescript can't model that very well)
    // do an extra test.
    // Since json compatible data shouldn't have methods, and IFluidHandle requires one, use that as a redundant check:
    const getMember = value.get;
    if (typeof getMember !== "function") {
        return false;
    }
    return isHandle;
}
exports.isFluidHandle = isFluidHandle;
function assertAllowedValue(value) {
    (0, internal_1.assert)(isTreeValue(value), 0x843 /* invalid value */);
}
exports.assertAllowedValue = assertAllowedValue;
/**
 * Checks if a value is a {@link TreeValue}.
 */
function isTreeValue(nodeValue) {
    switch (typeof nodeValue) {
        case "string":
        case "number":
        case "boolean":
            return true;
        default:
            return nodeValue === null || isFluidHandle(nodeValue);
    }
}
exports.isTreeValue = isTreeValue;
//# sourceMappingURL=valueUtilities.js.map