"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 optionalFieldChangeFormat_1 = require("./optionalFieldChangeFormat");
exports.noChangeCodecFamily = (0, codec_1.makeCodecFamily)([[0, codec_1.unitCodec]]);
const makeOptionalFieldCodecFamily = (childCodec) => (0, codec_1.makeCodecFamily)([[0, makeOptionalFieldCodec(childCodec)]]);
exports.makeOptionalFieldCodecFamily = makeOptionalFieldCodecFamily;
const registerIdCodec = {
    encode: (registerId) => {
        if (registerId === "self") {
            return 0;
        }
        return { ...registerId };
    },
    decode: (registerId) => {
        if (registerId === 0) {
            return "self";
        }
        return { ...registerId };
    },
};
function makeOptionalFieldCodec(childCodec) {
    return {
        encode: (change) => {
            const encoded = {};
            if (change.build.length > 0) {
                const builds = [];
                for (const build of change.build) {
                    builds.push([build.id, build.set]);
                }
                encoded.b = builds;
            }
            if (change.moves.length > 0) {
                encoded.m = [];
                for (const [src, dst, type] of change.moves) {
                    encoded.m.push([
                        registerIdCodec.encode(src),
                        registerIdCodec.encode(dst),
                        type === "nodeTargeting",
                    ]);
                }
            }
            if (change.childChanges.length > 0) {
                encoded.c = [];
                for (const [id, childChange] of change.childChanges) {
                    encoded.c.push([registerIdCodec.encode(id), childCodec.encode(childChange)]);
                }
            }
            if (change.reservedDetachId !== undefined) {
                encoded.d = registerIdCodec.encode(change.reservedDetachId);
            }
            return encoded;
        },
        decode: (encoded) => {
            const moves = encoded.m?.map(([src, dst, type]) => [
                registerIdCodec.decode(src),
                registerIdCodec.decode(dst),
                type ? "nodeTargeting" : "cellTargeting",
            ]) ?? [];
            const decoded = {
                build: encoded.b?.map(([id, set]) => ({
                    id,
                    set,
                })) ?? [],
                moves,
                childChanges: encoded.c?.map(([id, encodedChange]) => [
                    registerIdCodec.decode(id),
                    childCodec.decode(encodedChange),
                ]) ?? [],
            };
            if (encoded.d !== undefined) {
                decoded.reservedDetachId = registerIdCodec.decode(encoded.d);
            }
            return decoded;
        },
        encodedSchema: (0, optionalFieldChangeFormat_1.EncodedOptionalChangeset)(childCodec.encodedSchema ?? typebox_1.Type.Any()),
    };
}
//# sourceMappingURL=optionalFieldCodecs.js.map