/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { Type } from "@sinclair/typebox";
import { makeCodecFamily, unitCodec } from "../../codec";
import { jsonableTreeFromCursor, singleTextCursor } from "../treeTextCursor";
import { EncodedOptionalChangeset, EncodedNodeUpdate } from "./defaultFieldChangeFormat";
export const noChangeCodecFamily = makeCodecFamily([[0, unitCodec]]);
export const makeOptionalFieldCodecFamily = (childCodec) => makeCodecFamily([[0, makeOptionalFieldCodec(childCodec)]]);
function makeOptionalFieldCodec(childCodec) {
    const nodeUpdateCodec = makeNodeUpdateCodec(childCodec);
    return {
        encode: (change) => {
            const encoded = {};
            if (change.fieldChange !== undefined) {
                encoded.fieldChange = {
                    id: change.fieldChange.id,
                    wasEmpty: change.fieldChange.wasEmpty,
                };
                if (change.fieldChange.revision !== undefined) {
                    encoded.fieldChange.revision = change.fieldChange.revision;
                }
                if (change.fieldChange.newContent !== undefined) {
                    encoded.fieldChange.newContent = nodeUpdateCodec.encode(change.fieldChange.newContent);
                }
            }
            if (change.childChanges !== undefined) {
                encoded.childChanges = change.childChanges.map(([id, childChange]) => [
                    id,
                    childCodec.encode(childChange),
                ]);
            }
            return encoded;
        },
        decode: (encoded) => {
            const decoded = {};
            if (encoded.fieldChange !== undefined) {
                const decodedFieldChange = {
                    id: encoded.fieldChange.id,
                    wasEmpty: encoded.fieldChange.wasEmpty,
                };
                if (encoded.fieldChange.revision !== undefined) {
                    decodedFieldChange.revision = encoded.fieldChange.revision;
                }
                if (encoded.fieldChange.newContent !== undefined) {
                    decodedFieldChange.newContent = nodeUpdateCodec.decode(encoded.fieldChange.newContent);
                }
                decoded.fieldChange = decodedFieldChange;
            }
            if (encoded.childChanges !== undefined) {
                decoded.childChanges = encoded.childChanges.map(([id, childChange]) => [
                    id,
                    childCodec.decode(childChange),
                ]);
            }
            return decoded;
        },
        encodedSchema: EncodedOptionalChangeset(childCodec.encodedSchema ?? Type.Any()),
    };
}
function makeNodeUpdateCodec(childCodec) {
    return {
        encode: (update) => {
            const encoded = "revert" in update
                ? {
                    revert: jsonableTreeFromCursor(update.revert),
                    changeId: update.changeId,
                }
                : {
                    set: update.set,
                };
            if (update.changes !== undefined) {
                encoded.changes = childCodec.encode(update.changes);
            }
            return encoded;
        },
        decode: (encoded) => {
            const decoded = "revert" in encoded
                ? {
                    revert: singleTextCursor(encoded.revert),
                    changeId: encoded.changeId,
                }
                : { set: encoded.set };
            if (encoded.changes !== undefined) {
                decoded.changes = childCodec.decode(encoded.changes);
            }
            return decoded;
        },
        encodedSchema: EncodedNodeUpdate(childCodec.encodedSchema ?? Type.Any()),
    };
}
//# sourceMappingURL=defaultFieldChangeCodecs.js.map