"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.getCodecTreeForChangeFormat = exports.dependenciesForChangeFormat = exports.SharedTreeChangeFormatVersion = exports.makeSharedTreeChangeCodecFamily = void 0;
const internal_1 = require("@fluidframework/core-utils/internal");
const index_js_1 = require("../codec/index.js");
const index_js_2 = require("../feature-libraries/index.js");
const index_js_3 = require("../util/index.js");
const sharedTreeChangeFormat_js_1 = require("./sharedTreeChangeFormat.js");
function makeSharedTreeChangeCodecFamily(modularChangeCodecFamily, options) {
    const versions = [...exports.dependenciesForChangeFormat.entries()].map(([format, { modularChange }]) => [
        format,
        makeSharedTreeChangeCodec(modularChangeCodecFamily.resolve(modularChange), options),
    ]);
    return (0, index_js_1.makeCodecFamily)(versions);
}
exports.makeSharedTreeChangeCodecFamily = makeSharedTreeChangeCodecFamily;
/**
 * The format version for `SharedTreeChange`.
 */
exports.SharedTreeChangeFormatVersion = (0, index_js_3.strictEnum)("SharedTreeChangeFormatVersion", {
    /**
     * Introduced prior to 2.0 and used beyond.
     * Reading capability must be maintained for backwards compatibility.
     * Writing capability needs to be maintained so long as {@link lowestMinVersionForCollab} is less than 2.2.0.
     */
    v3: 3,
    /**
     * Introduced in 2.2.0.
     * Was inadvertently made usable for writing in 2.43.0 (through configuredSharedTree) and remains available.
     * Reading capability must be maintained for backwards compatibility.
     * Writing capability could be dropped in favor of {@link SharedTreeChangeFormatVersion.v3},
     * but doing so would make the pattern of writable versions more complex and gain little
     * because the logic for this format is shared with {@link SharedTreeChangeFormatVersion.v3}.
     */
    v4: 4,
    /**
     * Introduced and made available for writing in 2.80.0
     * Adds support for "no change" constraints.
     */
    v5: 5,
});
/**
 * Defines for each SharedTree change format the corresponding dependent formats to use.
 * This is an arbitrary mapping that is injected in the SharedTree change codec.
 * Once an entry is defined and used in production, it cannot be changed.
 * This is because the format for the dependent formats are not explicitly versioned.
 * @remarks
 * SchemaFormatVersion (used by SchemaChangeFormat) is not included here since it is explicitly versioned.
 */
exports.dependenciesForChangeFormat = new Map([
    [
        exports.SharedTreeChangeFormatVersion.v3,
        {
            modularChange: index_js_2.ModularChangeFormatVersion.v3,
        },
    ],
    [
        exports.SharedTreeChangeFormatVersion.v4,
        {
            modularChange: index_js_2.ModularChangeFormatVersion.v4,
        },
    ],
    [
        exports.SharedTreeChangeFormatVersion.v5,
        {
            modularChange: index_js_2.ModularChangeFormatVersion.v5,
        },
    ],
]);
function getCodecTreeForChangeFormat(version, clientVersion) {
    const { modularChange } = exports.dependenciesForChangeFormat.get(version) ?? (0, internal_1.fail)(0xc78 /* Unknown change format */);
    return {
        name: "SharedTreeChange",
        version,
        children: [
            (0, index_js_2.getCodecTreeForModularChangeFormat)(modularChange),
            index_js_2.schemaCodecBuilder.getCodecTree(clientVersion),
        ],
    };
}
exports.getCodecTreeForChangeFormat = getCodecTreeForChangeFormat;
function makeSharedTreeChangeCodec(modularChangeCodec, codecOptions) {
    const schemaChangeCodec = (0, index_js_2.makeSchemaChangeCodec)(codecOptions);
    const decoderLibrary = new index_js_1.DiscriminatedUnionDispatcher({
        data(encoded, context) {
            return {
                type: "data",
                innerChange: modularChangeCodec.decode(encoded, context),
            };
        },
        schema(encoded) {
            return {
                type: "schema",
                innerChange: schemaChangeCodec.decode(encoded),
            };
        },
    });
    return (0, index_js_1.withSchemaValidation)((0, sharedTreeChangeFormat_js_1.EncodedSharedTreeChange)(schemaChangeCodec.encodedSchema), {
        encode: (change, context) => {
            const changes = [];
            let updatedSchema;
            for (const decodedChange of change.changes) {
                if (decodedChange.type === "data") {
                    const schemaAndPolicy = updatedSchema === undefined
                        ? context.schema
                        : {
                            policy: context.schema === undefined
                                ? index_js_2.defaultSchemaPolicy
                                : context.schema.policy,
                            schema: updatedSchema,
                        };
                    changes.push({
                        data: modularChangeCodec.encode(decodedChange.innerChange, {
                            originatorId: context.originatorId,
                            schema: schemaAndPolicy,
                            idCompressor: context.idCompressor,
                            revision: context.revision,
                            isSummary: context.isSummary,
                        }),
                    });
                }
                else if (decodedChange.type === "schema") {
                    changes.push({
                        schema: schemaChangeCodec.encode(decodedChange.innerChange),
                    });
                    updatedSchema = decodedChange.innerChange.schema.new;
                }
            }
            return changes;
        },
        decode: (encodedChange, context) => {
            const changes = [];
            for (const subChange of encodedChange) {
                changes.push(decoderLibrary.dispatch(subChange, context));
            }
            return { changes };
        },
    }, codecOptions.jsonValidator);
}
//# sourceMappingURL=sharedTreeChangeCodecs.js.map