"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.sequenceFieldToDelta = void 0;
const common_utils_1 = require("@fluidframework/common-utils");
const util_1 = require("../../util");
const core_1 = require("../../core");
const deltaUtils_1 = require("../deltaUtils");
const treeTextCursor_1 = require("../treeTextCursor");
const format_1 = require("./format");
const utils_1 = require("./utils");
function sequenceFieldToDelta(marks, deltaFromChild) {
    const out = new util_1.OffsetListFactory();
    for (const mark of marks) {
        if (!(0, utils_1.areInputCellsEmpty)(mark) && !(0, utils_1.areOutputCellsEmpty)(mark)) {
            out.push(deltaFromNodeChange((0, utils_1.getNodeChange)(mark), (0, utils_1.getMarkLength)(mark), deltaFromChild));
        }
        else if ((0, utils_1.areInputCellsEmpty)(mark) && (0, utils_1.areOutputCellsEmpty)(mark)) {
        }
        else {
            // Inline into `switch(mark.type)` once we upgrade to TS 4.7
            const type = mark.type;
            (0, common_utils_1.assert)(type !== format_1.NoopMarkType, 0x6b0 /* Cell changing mark must no be a NoopMark */);
            switch (type) {
                case "Insert": {
                    const cursors = mark.content.map(treeTextCursor_1.singleTextCursor);
                    const insertMark = {
                        type: core_1.Delta.MarkType.Insert,
                        content: cursors,
                    };
                    populateChildModificationsIfAny(mark.changes, insertMark, deltaFromChild);
                    out.pushContent(insertMark);
                    break;
                }
                case "MoveIn":
                case "ReturnTo": {
                    const moveMark = {
                        type: core_1.Delta.MarkType.MoveIn,
                        count: mark.count,
                        moveId: (0, util_1.brandOpaque)(mark.id),
                    };
                    out.pushContent(moveMark);
                    break;
                }
                case "Modify": {
                    const modify = deltaFromChild(mark.changes);
                    if (Object.prototype.hasOwnProperty.call(modify, "setValue") ||
                        modify.fields !== undefined) {
                        out.pushContent(modify);
                    }
                    else {
                        out.pushOffset(1);
                    }
                    break;
                }
                case "Delete": {
                    const deleteMark = {
                        type: core_1.Delta.MarkType.Delete,
                        count: mark.count,
                    };
                    populateChildModificationsIfAny(mark.changes, deleteMark, deltaFromChild);
                    out.pushContent(deleteMark);
                    break;
                }
                case "MoveOut":
                case "ReturnFrom": {
                    const moveMark = {
                        type: core_1.Delta.MarkType.MoveOut,
                        moveId: (0, util_1.brandOpaque)(mark.id),
                        count: mark.count,
                    };
                    populateChildModificationsIfAny(mark.changes, moveMark, deltaFromChild);
                    out.pushContent(moveMark);
                    break;
                }
                case "Revive": {
                    const insertMark = {
                        type: core_1.Delta.MarkType.Insert,
                        content: mark.content,
                    };
                    populateChildModificationsIfAny(mark.changes, insertMark, deltaFromChild);
                    out.pushContent(insertMark);
                    break;
                }
                default:
                    (0, common_utils_1.unreachableCase)(type);
            }
        }
    }
    return out.list;
}
exports.sequenceFieldToDelta = sequenceFieldToDelta;
function populateChildModificationsIfAny(changes, deltaMark, deltaFromChild) {
    if (changes !== undefined) {
        const modify = deltaFromChild(changes);
        (0, deltaUtils_1.populateChildModifications)(modify, deltaMark);
    }
}
function deltaFromNodeChange(change, length, deltaFromChild) {
    if (change === undefined) {
        return length;
    }
    (0, common_utils_1.assert)(length === 1, 0x6a3 /* Modifying mark must be length one */);
    const modify = deltaFromChild(change);
    return isEmptyModify(modify) ? 1 : modify;
}
function isEmptyModify(modify) {
    return modify.fields === undefined && modify.setValue === undefined;
}
//# sourceMappingURL=sequenceFieldToDelta.js.map