"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.relevantRemovedRoots = void 0;
const internal_1 = require("@fluidframework/core-utils/internal");
const index_js_1 = require("../../core/index.js");
const deltaUtils_js_1 = require("../deltaUtils.js");
const utils_js_1 = require("./utils.js");
function* relevantRemovedRoots({ change, revision }, relevantRemovedRootsFromChild) {
    for (const mark of change) {
        if (refersToRelevantRemovedRoots(mark)) {
            (0, internal_1.assert)(mark.cellId !== undefined, 0x81d /* marks referring to removed trees must have an assigned cell ID */);
            const nodeId = (0, deltaUtils_js_1.nodeIdFromChangeAtom)(mark.cellId, revision);
            for (let i = 0; i < mark.count; i += 1) {
                yield (0, index_js_1.offsetDetachId)(nodeId, i);
            }
        }
        if (mark.changes !== undefined) {
            yield* relevantRemovedRootsFromChild(mark.changes);
        }
    }
}
exports.relevantRemovedRoots = relevantRemovedRoots;
function refersToRelevantRemovedRoots(mark) {
    if (mark.cellId !== undefined) {
        const effect = (0, utils_js_1.isAttachAndDetachEffect)(mark) ? mark.attach : mark;
        if ((0, utils_js_1.isInsert)(effect)) {
            // This tree is being inserted or restored.
            return true;
        }
        else if ((0, utils_js_1.isDetachOfRemovedNodes)(mark)) {
            // This removed tree is being restored as part of a detach.
            return true;
        }
        if (mark.changes !== undefined) {
            // This removed tree is being edited.
            // Note: there is a possibility that the child changes only affect a distant descendant
            // which may have been removed from this (removed) subtree. In such a case, this tree is not truly
            // relevant, but including it is the conservative thing to do.
            // In the future, we may represent changes to removed trees using the ID of the lowest removed
            // ancestor, which would allow us to avoid including such trees when they truly are not needed.
            return true;
        }
    }
    return false;
}
//# sourceMappingURL=relevantRemovedRoots.js.map