"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.PropertiesManager = exports.PropertiesRollback = void 0;
/* eslint-disable @typescript-eslint/no-non-null-assertion */
const core_utils_1 = require("@fluidframework/core-utils");
const constants_1 = require("./constants.cjs");
// eslint-disable-next-line import/no-deprecated
const properties_1 = require("./properties.cjs");
/**
 * @alpha
 */
var PropertiesRollback;
(function (PropertiesRollback) {
    /** Not in a rollback */
    PropertiesRollback[PropertiesRollback["None"] = 0] = "None";
    /** Rollback */
    PropertiesRollback[PropertiesRollback["Rollback"] = 1] = "Rollback";
})(PropertiesRollback || (exports.PropertiesRollback = PropertiesRollback = {}));
/**
 * @alpha
 */
class PropertiesManager {
    ackPendingProperties(annotateOp) {
        this.decrementPendingCounts(annotateOp.props);
    }
    decrementPendingCounts(props) {
        for (const key of Object.keys(props)) {
            if (this.pendingKeyUpdateCount?.[key] !== undefined) {
                (0, core_utils_1.assert)(this.pendingKeyUpdateCount[key] > 0, 0x05c /* "Trying to update more annotate props than do exist!" */);
                this.pendingKeyUpdateCount[key]--;
                if (this.pendingKeyUpdateCount?.[key] === 0) {
                    // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
                    delete this.pendingKeyUpdateCount[key];
                }
            }
        }
    }
    addProperties(oldProps, newProps, seq, collaborating = false, rollback = PropertiesRollback.None) {
        // eslint-disable-next-line import/no-deprecated
        this.pendingKeyUpdateCount ?? (this.pendingKeyUpdateCount = (0, properties_1.createMap)());
        // Clean up counts for rolled back edits before modifying oldProps
        if (collaborating && rollback === PropertiesRollback.Rollback) {
            this.decrementPendingCounts(newProps);
        }
        const shouldModifyKey = (key) => {
            if (seq === constants_1.UnassignedSequenceNumber ||
                seq === constants_1.UniversalSequenceNumber ||
                this.pendingKeyUpdateCount?.[key] === undefined) {
                return true;
            }
            return false;
        };
        const deltas = {};
        for (const key of Object.keys(newProps)) {
            if (collaborating) {
                if (seq === constants_1.UnassignedSequenceNumber) {
                    if (this.pendingKeyUpdateCount?.[key] === undefined) {
                        this.pendingKeyUpdateCount[key] = 0;
                    }
                    this.pendingKeyUpdateCount[key]++;
                }
                else if (!shouldModifyKey(key)) {
                    continue;
                }
            }
            const previousValue = oldProps[key];
            // The delta should be null if undefined, as that's how we encode delete
            deltas[key] = previousValue === undefined ? null : previousValue;
            const newValue = newProps[key];
            if (newValue === null) {
                // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
                delete oldProps[key];
            }
            else {
                oldProps[key] = newValue;
            }
        }
        return deltas;
    }
    copyTo(oldProps, newProps, newManager) {
        if (oldProps) {
            // eslint-disable-next-line no-param-reassign, import/no-deprecated
            newProps ?? (newProps = (0, properties_1.createMap)());
            if (!newManager) {
                throw new Error("Must provide new PropertyManager");
            }
            for (const key of Object.keys(oldProps)) {
                newProps[key] = oldProps[key];
            }
            // eslint-disable-next-line import/no-deprecated
            newManager.pendingKeyUpdateCount = (0, properties_1.createMap)();
            for (const key of Object.keys(this.pendingKeyUpdateCount)) {
                newManager.pendingKeyUpdateCount[key] = this.pendingKeyUpdateCount[key];
            }
        }
        return newProps;
    }
    hasPendingProperties() {
        return Object.keys(this.pendingKeyUpdateCount).length > 0;
    }
    hasPendingProperty(key) {
        return (this.pendingKeyUpdateCount?.[key] ?? 0) > 0;
    }
}
exports.PropertiesManager = PropertiesManager;
//# sourceMappingURL=segmentPropertiesManager.cjs.map