"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.cmpSchema = exports.cmp = void 0;
const deepEqual_1 = require("@jsonjoy.com/util/lib/json-equal/deepEqual");
const nodes_1 = require("../nodes");
const model_1 = require("../model");
/**
 * Deeply checks if two JSON nodes have the same schema and values. Does not
 * verify that the CRDT metadata (like timestamps) are the same, only that
 * the structure and values are equal.
 *
 * @param a The first JSON CRDT node.
 * @param b The second JSON CRDT node.
 * @returns True if the schemas and values are equal, false otherwise.
 */
const cmp = (a, b, compareContent) => {
    if (a === b)
        return true;
    if (a instanceof nodes_1.ConNode)
        return b instanceof nodes_1.ConNode && (!compareContent || (0, deepEqual_1.deepEqual)(a.val, b.val));
    else if (a instanceof nodes_1.ValNode)
        return b instanceof nodes_1.ValNode && (0, exports.cmp)(a.node(), b.node(), compareContent);
    else if (a instanceof nodes_1.StrNode)
        return b instanceof nodes_1.StrNode && (!compareContent || (a.length() === b.length() && a.view() === b.view()));
    else if (a instanceof nodes_1.ObjNode) {
        if (!(b instanceof nodes_1.ObjNode))
            return false;
        const keys1 = a.keys;
        const keys2 = b.keys;
        const length1 = keys1.size;
        const length2 = keys2.size;
        if (length1 !== length2)
            return false;
        for (const key of keys1.keys()) {
            if (!keys2.has(key))
                return false;
            if (!(0, exports.cmp)(a.get(key), b.get(key), compareContent))
                return false;
        }
        return true;
    }
    else if (a instanceof nodes_1.ArrNode) {
        if (!(b instanceof nodes_1.ArrNode))
            return false;
        const length = a.length();
        if (length !== b.length())
            return false;
        for (let i = 0; i < length; i++)
            if (!(0, exports.cmp)(a.getNode(i), b.getNode(i), compareContent))
                return false;
        return true;
    }
    else if (a instanceof nodes_1.VecNode) {
        if (!(b instanceof nodes_1.VecNode))
            return false;
        const length = a.length();
        if (length !== b.length())
            return false;
        for (let i = 0; i < length; i++)
            if (!(0, exports.cmp)(a.get(i), b.get(i), compareContent))
                return false;
        return true;
    }
    else if (a instanceof nodes_1.BinNode)
        return b instanceof nodes_1.BinNode && (!compareContent || (a.length() === b.length() && (0, deepEqual_1.deepEqual)(a.view(), b.view())));
    return false;
};
exports.cmp = cmp;
const cmpSchema = (a, b, compareContent) => {
    const model1 = model_1.Model.create(a);
    const model2 = model_1.Model.create(b);
    return (0, exports.cmp)(model1.root, model2.root, compareContent);
};
exports.cmpSchema = cmpSchema;
//# sourceMappingURL=index.js.map