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