"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
const assert_1 = require("assert");
const constants_1 = require("../constants.cjs");
const mergeTreeDeltaCallback_1 = require("../mergeTreeDeltaCallback.cjs");
const ops_1 = require("../ops.cjs");
const textSegment_1 = require("../textSegment.cjs");
const mergeTree_1 = require("../mergeTree.cjs");
const testUtils_1 = require("./testUtils.cjs");
describe("MergeTree", () => {
    let mergeTree;
    const localClientId = 17;
    let currentSequenceNumber;
    beforeEach(() => {
        mergeTree = new mergeTree_1.MergeTree();
        (0, testUtils_1.insertSegments)({
            mergeTree,
            pos: 0,
            segments: [textSegment_1.TextSegment.make("hello world!")],
            refSeq: constants_1.UniversalSequenceNumber,
            clientId: constants_1.LocalClientId,
            seq: constants_1.UniversalSequenceNumber,
            opArgs: undefined,
        });
        currentSequenceNumber = 0;
        mergeTree.startCollaboration(localClientId, 
        /* minSeq: */ currentSequenceNumber, 
        /* currentSeq: */ currentSequenceNumber);
    });
    describe("markRangeRemoved", () => {
        it("Event on Removal", () => {
            const count = (0, testUtils_1.countOperations)(mergeTree);
            (0, testUtils_1.markRangeRemoved)({
                mergeTree,
                start: 4,
                end: 6,
                refSeq: currentSequenceNumber,
                clientId: localClientId,
                seq: constants_1.UnassignedSequenceNumber,
                overwrite: false,
                opArgs: undefined,
            });
            assert_1.strict.deepStrictEqual(count, {
                [ops_1.MergeTreeDeltaType.REMOVE]: 1,
                [mergeTreeDeltaCallback_1.MergeTreeMaintenanceType.SPLIT]: 2,
            });
        });
        // Verify that zamboni unlinks a removed segment and raises the appropriate maintenance event.
        it("Event on Unlink", () => {
            const count = (0, testUtils_1.countOperations)(mergeTree);
            const start = 4;
            const end = 6;
            (0, testUtils_1.markRangeRemoved)({
                mergeTree,
                start,
                end,
                refSeq: currentSequenceNumber,
                clientId: localClientId,
                seq: constants_1.UnassignedSequenceNumber,
                overwrite: false,
                opArgs: undefined,
            });
            // In order for the removed segment to unlinked by zamboni, we need to ACK the segment
            // and advance the collaboration window's minSeq past the removedSeq.
            mergeTree.ackPendingSegment({
                op: {
                    pos1: start,
                    pos2: end,
                    type: ops_1.MergeTreeDeltaType.REMOVE,
                },
                sequencedMessage: {
                    sequenceNumber: ++currentSequenceNumber,
                },
            });
            // Move currentSeq/minSeq past the seq# at which the removal was ACKed.
            mergeTree.collabWindow.currentSeq = currentSequenceNumber;
            mergeTree.setMinSeq(currentSequenceNumber);
            assert_1.strict.deepStrictEqual(count, {
                [ops_1.MergeTreeDeltaType.REMOVE]: 1,
                [mergeTreeDeltaCallback_1.MergeTreeMaintenanceType.SPLIT]: 2,
                [mergeTreeDeltaCallback_1.MergeTreeMaintenanceType.UNLINK]: 1,
                [mergeTreeDeltaCallback_1.MergeTreeMaintenanceType.ACKNOWLEDGED]: 1,
            });
        });
        it("Remote Before Local", () => {
            const remoteClientId = 35;
            let remoteSequenceNumber = currentSequenceNumber;
            (0, testUtils_1.markRangeRemoved)({
                mergeTree,
                start: 4,
                end: 6,
                refSeq: remoteSequenceNumber,
                clientId: remoteClientId,
                seq: ++remoteSequenceNumber,
                overwrite: false,
                opArgs: undefined,
            });
            const count = (0, testUtils_1.countOperations)(mergeTree);
            (0, testUtils_1.markRangeRemoved)({
                mergeTree,
                start: 3,
                end: 5,
                refSeq: currentSequenceNumber,
                clientId: localClientId,
                seq: constants_1.UnassignedSequenceNumber,
                overwrite: false,
                opArgs: undefined,
            });
            assert_1.strict.deepStrictEqual(count, {
                [ops_1.MergeTreeDeltaType.REMOVE]: 1,
                [mergeTreeDeltaCallback_1.MergeTreeMaintenanceType.SPLIT]: 2,
            });
        });
        it("Local Before Remote", () => {
            const remoteClientId = 35;
            let remoteSequenceNumber = currentSequenceNumber;
            (0, testUtils_1.markRangeRemoved)({
                mergeTree,
                start: 4,
                end: 6,
                refSeq: currentSequenceNumber,
                clientId: localClientId,
                seq: constants_1.UnassignedSequenceNumber,
                overwrite: false,
                opArgs: undefined,
            });
            const count = (0, testUtils_1.countOperations)(mergeTree);
            (0, testUtils_1.markRangeRemoved)({
                mergeTree,
                start: 3,
                end: 5,
                refSeq: remoteSequenceNumber,
                clientId: remoteClientId,
                seq: ++remoteSequenceNumber,
                overwrite: false,
                opArgs: undefined,
            });
            assert_1.strict.deepStrictEqual(count, {
                [ops_1.MergeTreeDeltaType.REMOVE]: 1,
                [mergeTreeDeltaCallback_1.MergeTreeMaintenanceType.SPLIT]: 2,
            });
        });
        it("Local delete shadows remote", () => {
            const remoteClientId = 35;
            let remoteSequenceNumber = currentSequenceNumber;
            (0, testUtils_1.markRangeRemoved)({
                mergeTree,
                start: 3,
                end: 6,
                refSeq: currentSequenceNumber,
                clientId: localClientId,
                seq: constants_1.UnassignedSequenceNumber,
                overwrite: false,
                opArgs: undefined,
            });
            const count = (0, testUtils_1.countOperations)(mergeTree);
            (0, testUtils_1.markRangeRemoved)({
                mergeTree,
                start: 4,
                end: 5,
                refSeq: remoteSequenceNumber,
                clientId: remoteClientId,
                seq: ++remoteSequenceNumber,
                overwrite: false,
                opArgs: undefined,
            });
            assert_1.strict.deepStrictEqual(count, {
                /* MergeTreeDeltaType.REMOVE is absent as it should not be fired. */
                [mergeTreeDeltaCallback_1.MergeTreeMaintenanceType.SPLIT]: 2,
            });
        });
    });
});
//# sourceMappingURL=mergeTree.markRangeRemoved.deltaCallback.spec.cjs.map