"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable @typescript-eslint/no-non-null-assertion */
const node_assert_1 = require("node:assert");
const stochastic_test_utils_1 = require("@fluid-private/stochastic-test-utils");
const localReference_js_1 = require("../localReference.js");
const ops_js_1 = require("../ops.js");
const mergeTreeOperationRunner_js_1 = require("./mergeTreeOperationRunner.js");
const testClient_js_1 = require("./testClient.js");
const testClientLogger_js_1 = require("./testClientLogger.js");
const testUtils_js_1 = require("./testUtils.js");
const defaultOptions = {
    initLen: { min: 2, max: 256 },
    modLen: { min: 1, max: 256 },
    opsPerRoundRange: { min: 10, max: 10 },
    rounds: 10,
    operations: [mergeTreeOperationRunner_js_1.removeRange],
    growthFunc: (input) => input * 2,
};
describe("MergeTree.Client", () => {
    beforeEach(() => {
        (0, localReference_js_1.setValidateRefCount)(testUtils_js_1.validateRefCount);
    });
    afterEach(() => {
        (0, localReference_js_1.setValidateRefCount)(undefined);
    });
    // Generate a list of single character client names, support up to 69 clients
    const clientNames = (0, mergeTreeOperationRunner_js_1.generateClientNames)();
    (0, mergeTreeOperationRunner_js_1.doOverRanges)(defaultOptions, ({ initLen, modLen }) => {
        it(`LocalReferenceFarm_${initLen}_${modLen}`, async () => {
            const random = (0, stochastic_test_utils_1.makeRandom)(0xdeadbeef, 0xfeedbed, initLen, modLen);
            const clients = Array.from({ length: 3 })
                .fill(0)
                .map(() => new testClient_js_1.TestClient());
            for (const [i, c] of clients.entries())
                c.startOrUpdateCollaboration(clientNames[i]);
            let seq = 0;
            // init with random values
            seq = (0, mergeTreeOperationRunner_js_1.runMergeTreeOperationRunner)(random, seq, clients, initLen, defaultOptions);
            // add local references
            const refs = [];
            const validateRefs = (reason, workload) => {
                const preWorkload = testClientLogger_js_1.TestClientLogger.toString(clients);
                workload();
                for (let c = 1; c < clients.length; c++) {
                    for (let r = 0; r < refs[c].length; r++) {
                        const pos0 = clients[0].localReferencePositionToPosition(refs[0][r]);
                        const posC = clients[c].localReferencePositionToPosition(refs[c][r]);
                        if (pos0 !== posC) {
                            node_assert_1.strict.equal(pos0, posC, `${reason}:\n${preWorkload}\n${testClientLogger_js_1.TestClientLogger.toString(clients)}`);
                        }
                    }
                }
                // console.log(`${reason}:\n${preWorkload}\n${TestClientLogger.toString(clients)}`)
            };
            validateRefs("Initialize", () => {
                for (const [i, c] of clients.entries()) {
                    refs.push([]);
                    for (let t = 0; t < c.getLength(); t++) {
                        const seg = c.getContainingSegment(t);
                        const forwardLref = c.createLocalReferencePosition(seg.segment, seg.offset, ops_js_1.ReferenceType.SlideOnRemove, { t }, localReference_js_1.SlidingPreference.FORWARD);
                        const backwardLref = c.createLocalReferencePosition(seg.segment, seg.offset, ops_js_1.ReferenceType.SlideOnRemove, { t }, localReference_js_1.SlidingPreference.BACKWARD);
                        refs[i].push(forwardLref, backwardLref);
                    }
                }
            });
            validateRefs("After Init Zamboni", () => {
                // trigger zamboni multiple times as it is incremental
                for (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {
                    for (const c of clients)
                        c.updateMinSeq(i);
                }
            });
            validateRefs("After More Ops", () => {
                // init with random values
                seq = (0, mergeTreeOperationRunner_js_1.runMergeTreeOperationRunner)(random, seq, clients, modLen, defaultOptions);
            });
            validateRefs("After Final Zamboni", () => {
                // trigger zamboni multiple times as it is incremental
                for (let i = clients[0].getCollabWindow().minSeq; i <= seq; i++) {
                    for (const c of clients)
                        c.updateMinSeq(i);
                }
            });
        });
    });
});
//# sourceMappingURL=client.localReferenceFarm.spec.js.map