/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { makeVersionedValidatedCodec, } from "../codec/index.js";
import { JsonCompatibleReadOnlySchema, mapIterable, } from "../util/index.js";
import { EncodedEditManager, version, } from "./editManagerFormat.js";
export function makeEditManagerCodec(changeCodec, revisionTagCodec, options) {
    const format = EncodedEditManager(changeCodec.json.encodedSchema ?? JsonCompatibleReadOnlySchema);
    const encodeCommit = (commit, context) => ({
        ...commit,
        revision: revisionTagCodec.encode(commit.revision, { originatorId: commit.sessionId }),
        change: changeCodec.json.encode(commit.change, context),
    });
    const decodeCommit = (commit, context) => ({
        ...commit,
        revision: revisionTagCodec.decode(commit.revision, { originatorId: commit.sessionId }),
        change: changeCodec.json.decode(commit.change, context),
    });
    const codec = makeVersionedValidatedCodec(options, new Set([version]), format, {
        encode: (data, context) => {
            const json = {
                trunk: data.trunk.map((commit) => encodeCommit(commit, {
                    originatorId: commit.sessionId,
                    schema: context.schema,
                })),
                branches: Array.from(data.peerLocalBranches.entries(), ([sessionId, branch]) => [
                    sessionId,
                    {
                        base: revisionTagCodec.encode(branch.base, {
                            originatorId: sessionId,
                        }),
                        commits: branch.commits.map((commit) => encodeCommit(commit, {
                            originatorId: commit.sessionId,
                            schema: context.schema,
                        })),
                    },
                ]),
                version,
            };
            return json;
        },
        decode: (json) => {
            // TODO: sort out EncodedCommit vs Commit, and make this type check without `any`.
            const trunk = json.trunk;
            return {
                trunk: trunk.map((commit) => 
                // TODO: sort out EncodedCommit vs Commit, and make this type check without `as`.
                // eslint-disable-next-line @typescript-eslint/no-unsafe-return
                decodeCommit(commit, {
                    originatorId: commit.sessionId,
                })),
                peerLocalBranches: new Map(mapIterable(json.branches, ([sessionId, branch]) => [
                    sessionId,
                    {
                        base: revisionTagCodec.decode(branch.base, { originatorId: sessionId }),
                        commits: branch.commits.map((commit) => 
                        // TODO: sort out EncodedCommit vs Commit, and make this type check without `as`.
                        decodeCommit(commit, {
                            originatorId: commit.sessionId,
                        })),
                    },
                ])),
            };
        },
    });
    // TODO: makeVersionedValidatedCodec and withSchemaValidation should allow the codec to decode JsonCompatibleReadOnly, or Versioned or something like that,
    // and not leak the internal encoded format in the API surface.
    // Fixing that would remove the need for this cast.
    return codec;
}
//# sourceMappingURL=editManagerCodecs.js.map