/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { unreachableCase } from "@fluidframework/common-utils";
import { makeCodecFamily } from "../../codec";
import { jsonableTreeFromCursor, singleTextCursor } from "../treeTextCursor";
import { NoopMarkType } from "./format";
export const sequenceFieldChangeCodecFactory = (childCodec) => makeCodecFamily([
    [
        0,
        {
            encode: (changeset) => encodeForJson(changeset, childCodec),
            decode: (changeset) => decodeJson(changeset, childCodec),
        },
    ],
]);
function encodeForJson(markList, childCodec) {
    const jsonMarks = [];
    for (const mark of markList) {
        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(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 NoopMarkType:
            case "MoveIn":
            case "ReturnTo":
                jsonMarks.push(mark);
                break;
            default:
                unreachableCase(type);
        }
    }
    return jsonMarks;
}
function decodeJson(change, childCodec) {
    const marks = [];
    const array = change;
    for (const mark of array) {
        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(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 NoopMarkType:
            case "MoveIn":
            case "ReturnTo":
                marks.push(mark);
                break;
            default:
                unreachableCase(type);
        }
    }
    return marks;
}
//# sourceMappingURL=sequenceFieldChangeEncoder.js.map