/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { assert, unreachableCase } from "@fluidframework/core-utils/internal";
import { getLast, hasSome } from "../../util/index.js";
import { nodeIdFromChangeAtom } from "../deltaUtils.js";
import { NoopMarkType } from "./types.js";
import { areInputCellsEmpty, areOutputCellsEmpty, getAttachedRootId, getDetachedRootId, getInputCellId, } from "./utils.js";
export function sequenceFieldToDelta(change, deltaFromChild) {
    const deltaMarks = [];
    for (const mark of change) {
        const deltaMark = { count: mark.count };
        const inputCellId = getInputCellId(mark);
        const changes = mark.changes;
        if (changes !== undefined && inputCellId === undefined) {
            const nestedDelta = deltaFromChild(changes);
            if (nestedDelta.size > 0) {
                deltaMark.fields = nestedDelta;
            }
        }
        if (!areInputCellsEmpty(mark) && !areOutputCellsEmpty(mark)) {
            // Since each cell is associated with exactly one node,
            // the cell starting end ending populated means the cell content has not changed.
            deltaMarks.push(deltaMark);
        }
        else {
            const type = mark.type;
            // Inline into `switch(mark.type)` once we upgrade to TS 4.7
            switch (type) {
                case "Remove": {
                    const newDetachId = getDetachedRootId(mark);
                    if (inputCellId === undefined) {
                        deltaMark.detach = nodeIdFromChangeAtom(newDetachId);
                        deltaMarks.push(deltaMark);
                    }
                    break;
                }
                case "Insert": {
                    const buildId = nodeIdFromChangeAtom(getAttachedRootId(mark));
                    deltaMark.attach = buildId;
                    deltaMarks.push(deltaMark);
                    break;
                }
                case NoopMarkType:
                    if (inputCellId === undefined) {
                        deltaMarks.push(deltaMark);
                    }
                    break;
                case "Rename":
                    assert(mark.cellId !== undefined, 0x9f9 /* Renames should only target empty cells */);
                    break;
                default:
                    unreachableCase(type);
            }
        }
    }
    // Remove trailing no-op marks
    while (hasSome(deltaMarks)) {
        const lastMark = getLast(deltaMarks);
        if (lastMark.attach !== undefined ||
            lastMark.detach !== undefined ||
            lastMark.fields !== undefined) {
            break;
        }
        deltaMarks.pop();
    }
    return deltaMarks;
}
//# sourceMappingURL=sequenceFieldToDelta.js.map