"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.sequenceFieldChangeCodecFactory = void 0;
const common_utils_1 = require("@fluidframework/common-utils");
const codec_1 = require("../../codec");
const treeTextCursor_1 = require("../treeTextCursor");
const utils_1 = require("./utils");
const sequenceFieldChangeCodecFactory = (childCodec) => (0, codec_1.makeCodecFamily)([
    [
        0,
        {
            encode: (changeset) => encodeForJson(changeset, childCodec),
            decode: (changeset) => decodeJson(changeset, childCodec),
        },
    ],
]);
exports.sequenceFieldChangeCodecFactory = sequenceFieldChangeCodecFactory;
function encodeForJson(markList, childCodec) {
    const jsonMarks = [];
    for (const mark of markList) {
        if ((0, utils_1.isSkipMark)(mark)) {
            jsonMarks.push(mark);
        }
        else {
            const type = mark.type;
            switch (type) {
                case "Insert":
                case "Delete":
                case "MoveOut":
                case "ReturnFrom":
                    if (mark.changes !== undefined) {
                        jsonMarks.push(Object.assign(Object.assign({}, mark), { changes: childCodec.encode(mark.changes) }));
                    }
                    else {
                        jsonMarks.push(mark);
                    }
                    break;
                case "Revive": {
                    const content = mark.content.map(treeTextCursor_1.jsonableTreeFromCursor);
                    if (mark.changes !== undefined) {
                        jsonMarks.push(Object.assign(Object.assign({}, mark), { content, changes: childCodec.encode(mark.changes) }));
                    }
                    else {
                        jsonMarks.push(Object.assign(Object.assign({}, mark), { content }));
                    }
                    break;
                }
                case "Modify":
                    jsonMarks.push(Object.assign(Object.assign({}, mark), { changes: childCodec.encode(mark.changes) }));
                    break;
                case "MoveIn":
                case "ReturnTo":
                    jsonMarks.push(mark);
                    break;
                default:
                    (0, common_utils_1.unreachableCase)(type);
            }
        }
    }
    return jsonMarks;
}
function decodeJson(change, childCodec) {
    const marks = [];
    const array = change;
    for (const mark of array) {
        if ((0, utils_1.isSkipMark)(mark)) {
            marks.push(mark);
        }
        else {
            const type = mark.type;
            switch (type) {
                case "Modify": {
                    marks.push(Object.assign(Object.assign({}, mark), { changes: childCodec.decode(mark.changes) }));
                    break;
                }
                case "Insert":
                case "Delete":
                case "MoveOut":
                case "ReturnFrom": {
                    if (mark.changes !== undefined) {
                        marks.push(Object.assign(Object.assign({}, mark), { changes: childCodec.decode(mark.changes) }));
                    }
                    else {
                        marks.push(mark);
                    }
                    break;
                }
                case "Revive": {
                    const content = mark.content.map(treeTextCursor_1.singleTextCursor);
                    if (mark.changes !== undefined) {
                        marks.push(Object.assign(Object.assign({}, mark), { content, changes: childCodec.decode(mark.changes) }));
                    }
                    else {
                        marks.push(Object.assign(Object.assign({}, mark), { content }));
                    }
                    break;
                }
                case "MoveIn":
                case "ReturnTo":
                    marks.push(mark);
                    break;
                default:
                    (0, common_utils_1.unreachableCase)(type);
            }
        }
    }
    return marks;
}
//# sourceMappingURL=sequenceFieldChangeEncoder.js.map