/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { unreachableCase } from "@fluidframework/core-utils/internal";
import { getConfigForMinVersionForCollab, lowestMinVersionForCollab, } from "@fluidframework/runtime-utils/internal";
import { FluidClientVersion, makeCodecFamily, makeDiscontinuedCodecVersion, makeVersionDispatchingCodec, } from "../codec/index.js";
import { brand } from "../util/index.js";
import { makeV1ToV4CodecWithVersion } from "./messageCodecV1ToV4.js";
import { makeV5CodecWithVersion } from "./messageCodecV5.js";
import { MessageFormatVersion, messageFormatVersions } from "./messageFormat.js";
/**
 * Convert a MinimumVersionForCollab to a MessageFormatVersion.
 * @param clientVersion - The MinimumVersionForCollab to convert.
 * @returns The MessageFormatVersion that corresponds to the provided MinimumVersionForCollab.
 */
export function clientVersionToMessageFormatVersion(clientVersion, writeVersionOverride) {
    const compatibleVersion = brand(getConfigForMinVersionForCollab(clientVersion, {
        [lowestMinVersionForCollab]: MessageFormatVersion.v3,
        [FluidClientVersion.v2_43]: MessageFormatVersion.v4,
    }));
    return writeVersionOverride ?? compatibleVersion;
}
function messageFormatVersionFromOptions(options) {
    const selector = options.messageFormatSelector ?? clientVersionToMessageFormatVersion;
    return selector(options.minVersionForCollab);
}
/**
 * Returns the version that should be used for testing shared branches.
 */
export function messageFormatVersionSelectorForSharedBranches(clientVersion) {
    return brand(MessageFormatVersion.v5);
}
export function makeMessageCodec(changeCodecs, dependentChangeFormatVersion, revisionTagCodec, options) {
    const family = makeMessageCodecs(changeCodecs, dependentChangeFormatVersion, revisionTagCodec, options);
    const writeVersion = messageFormatVersionFromOptions(options);
    return makeVersionDispatchingCodec(family, { ...options, writeVersion });
}
/**
 * @privateRemarks Exported for testing.
 */
export function makeMessageCodecs(changeCodecs, dependentChangeFormatVersion, revisionTagCodec, options) {
    const registry = Array.from(messageFormatVersions).map((version) => {
        switch (version) {
            case MessageFormatVersion.undefined:
            case MessageFormatVersion.v1:
            case MessageFormatVersion.v2: {
                const versionOrUndefined = version === MessageFormatVersion.undefined ? undefined : version;
                return [
                    versionOrUndefined,
                    makeDiscontinuedCodecVersion(options, versionOrUndefined, "2.73.0"),
                ];
            }
            case MessageFormatVersion.v3:
            case MessageFormatVersion.v4: {
                const changeCodec = changeCodecs.resolve(dependentChangeFormatVersion.lookup(version)).json;
                return [
                    version,
                    makeV1ToV4CodecWithVersion(changeCodec, revisionTagCodec, options, version),
                ];
            }
            case MessageFormatVersion.v5: {
                const changeCodec = changeCodecs.resolve(dependentChangeFormatVersion.lookup(version)).json;
                return [
                    version,
                    makeV5CodecWithVersion(changeCodec, revisionTagCodec, options, version),
                ];
            }
            default:
                unreachableCase(version);
        }
    });
    return makeCodecFamily(registry);
}
export function getCodecTreeForMessageFormatWithChange(clientVersion, changeFormat) {
    return {
        name: "Message",
        version: clientVersionToMessageFormatVersion(clientVersion),
        children: [changeFormat],
    };
}
//# sourceMappingURL=messageCodecs.js.map