/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { debugAssert } from "@fluidframework/core-utils/internal";
import { BTree, defaultComparator } from "@tylerbu/sorted-btree-es6";
// eslint-disable-next-line import-x/no-internal-modules
import { union } from "@tylerbu/sorted-btree-es6/extended/union";
import { brand } from "./brand.js";
/**
 * Create a new {@link TupleBTree}.
 * @param comparator - Either a single {@link TupleComparator | comparator} for all pairs of elements in the tuple or a {@link TupleComparators | tuple of comparators} that compares each pair of corresponding elements individually.
 * @param entries - Optional initial entries for the btree.
 */
export function newTupleBTree(comparator, entries) {
    return brand(new BTree(entries, comparator));
}
/**
 * Compares two tuples (arrays) element by element.
 * @param a - The first tuple to compare.
 * @param b - The second tuple to compare.
 * @returns The comparison of the first pair of elements at the same index that differ, or 0 if all elements are equal.
 * @remarks The tuples must be the same length and have the same type of elements in the same order.
 */
export function createTupleComparator(compare = defaultComparator) {
    return (a, b) => {
        debugAssert(() => a.length === b.length || "compareTuples requires arrays of the same length");
        const comparators = typeof compare === "function" ? undefined : compare;
        for (let i = 0; i < a.length; i++) {
            const comparator = comparators?.[i] ?? compare;
            const result = comparator(a[i], b[i]);
            if (result !== 0) {
                return result;
            }
        }
        return 0;
    };
}
/**
 * Merge the entries of two {@link TupleBTree}s.
 * @param tree1 - The first btree.
 * @param tree2 - The second btree.
 * This always returns a new btree and does not modify either input.
 * @param preferLeft - If true, colliding keys will use the value from `tree1`, otherwise the value from `tree2` is used.
 */
export function mergeTupleBTrees(tree1, tree2, preferLeft = true) {
    if (tree2 === undefined) {
        return brand(tree1.clone());
    }
    // Use efficient union operation from sorted-btree 2.x
    const result = union(tree1, tree2, (_key, val1, val2) => (preferLeft ? val1 : val2));
    return brand(result);
}
//# sourceMappingURL=bTreeUtils.js.map