"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.makeOptionalFieldCodecFamily = exports.noChangeCodecFamily = void 0;
const typebox_1 = require("@sinclair/typebox");
const codec_1 = require("../../codec");
const changeAtomIdCodec_1 = require("../changeAtomIdCodec");
const optionalFieldChangeFormat_1 = require("./optionalFieldChangeFormat");
exports.noChangeCodecFamily = (0, codec_1.makeCodecFamily)([
    [0, codec_1.unitCodec],
]);
const makeOptionalFieldCodecFamily = (childCodec, revisionTagCodec) => (0, codec_1.makeCodecFamily)([[0, makeOptionalFieldCodec(childCodec, revisionTagCodec)]]);
exports.makeOptionalFieldCodecFamily = makeOptionalFieldCodecFamily;
function makeRegisterIdCodec(revisionTagCodec) {
    const changeAtomIdCodec = (0, changeAtomIdCodec_1.makeChangeAtomIdCodec)(revisionTagCodec);
    return {
        encode: (registerId, originatorId) => {
            if (registerId === "self") {
                return null;
            }
            return changeAtomIdCodec.encode(registerId, originatorId);
        },
        decode: (registerId, originatorId) => {
            if (registerId === null) {
                return "self";
            }
            return changeAtomIdCodec.decode(registerId, originatorId);
        },
        encodedSchema: optionalFieldChangeFormat_1.EncodedRegisterId,
    };
}
function makeOptionalFieldCodec(childCodec, revisionTagCodec) {
    const registerIdCodec = makeRegisterIdCodec(revisionTagCodec);
    return {
        encode: (change, originatorId) => {
            const encoded = {};
            if (change.moves.length > 0) {
                encoded.m = [];
                for (const [src, dst, type] of change.moves) {
                    encoded.m.push([
                        registerIdCodec.encode(src, originatorId),
                        registerIdCodec.encode(dst, originatorId),
                        type === "nodeTargeting",
                    ]);
                }
            }
            if (change.childChanges.length > 0) {
                encoded.c = [];
                for (const [id, childChange] of change.childChanges) {
                    encoded.c.push([
                        registerIdCodec.encode(id, originatorId),
                        childCodec.encode(childChange, originatorId),
                    ]);
                }
            }
            if (change.reservedDetachId !== undefined) {
                encoded.d = registerIdCodec.encode(change.reservedDetachId, originatorId);
            }
            return encoded;
        },
        decode: (encoded, originatorId) => {
            const moves = encoded.m?.map(([src, dst, type]) => [
                registerIdCodec.decode(src, originatorId),
                registerIdCodec.decode(dst, originatorId),
                type ? "nodeTargeting" : "cellTargeting",
            ]) ?? [];
            const decoded = {
                moves,
                childChanges: encoded.c?.map(([id, encodedChange]) => [
                    registerIdCodec.decode(id, originatorId),
                    childCodec.decode(encodedChange, originatorId),
                ]) ?? [],
            };
            if (encoded.d !== undefined) {
                decoded.reservedDetachId = registerIdCodec.decode(encoded.d, originatorId);
            }
            return decoded;
        },
        encodedSchema: (0, optionalFieldChangeFormat_1.EncodedOptionalChangeset)(childCodec.encodedSchema ?? typebox_1.Type.Any()),
    };
}
//# sourceMappingURL=optionalFieldCodecs.js.map