/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { assert } from "@fluidframework/core-utils/internal";
import { mapIterable } from "../util/index.js";
import { decodeBranchId, encodeBranchId } from "./branchIdCodec.js";
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
function encodeCommit(changeCodec, revisionTagCodec, commit, context) {
    return {
        ...commit,
        revision: revisionTagCodec.encode(commit.revision, {
            originatorId: commit.sessionId,
            idCompressor: context.idCompressor,
            revision: undefined,
            isSummary: context.isSummary,
        }),
        change: changeCodec.encode(commit.change, { ...context, revision: commit.revision }),
    };
}
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
function decodeCommit(changeCodec, revisionTagCodec, commit, context) {
    const revision = revisionTagCodec.decode(commit.revision, {
        originatorId: commit.sessionId,
        idCompressor: context.idCompressor,
        revision: undefined,
        isSummary: context.isSummary,
    });
    return {
        ...commit,
        revision,
        change: changeCodec.decode(commit.change, { ...context, revision }),
    };
}
export function encodeSharedBranch(changeCodec, revisionTagCodec, data, context, originatorId) {
    const json = {
        trunk: data.trunk.map((commit) => encodeCommit(changeCodec, revisionTagCodec, commit, {
            originatorId: commit.sessionId,
            idCompressor: context.idCompressor,
            schema: context.schema,
            revision: undefined,
            isSummary: context.isSummary,
        })),
        peers: Array.from(data.peerLocalBranches.entries(), ([sessionId, branch]) => [
            sessionId,
            {
                base: revisionTagCodec.encode(branch.base, {
                    originatorId: sessionId,
                    idCompressor: context.idCompressor,
                    revision: undefined,
                    isSummary: context.isSummary,
                }),
                commits: branch.commits.map((commit) => encodeCommit(changeCodec, revisionTagCodec, commit, {
                    originatorId: commit.sessionId,
                    idCompressor: context.idCompressor,
                    schema: context.schema,
                    revision: undefined,
                    isSummary: context.isSummary,
                })),
            },
        ]),
    };
    if (data.session !== undefined) {
        json.session = data.session;
    }
    if (data.id !== undefined) {
        json.id = encodeBranchId(context.idCompressor, data.id);
    }
    if (data.name !== undefined) {
        json.name = data.name;
    }
    if (data.author !== undefined) {
        json.author = data.author;
    }
    if (data.base !== undefined) {
        assert(originatorId !== undefined, 0xc62 /* Cannot encode branch base without originatorId */);
        json.base = revisionTagCodec.encode(data.base, {
            originatorId,
            idCompressor: context.idCompressor,
            revision: undefined,
            isSummary: context.isSummary,
        });
    }
    return json;
}
export function decodeSharedBranch(changeCodec, revisionTagCodec, json, context, originatorId) {
    // TODO: sort out EncodedCommit vs Commit, and make this type check without type assertion.
    const trunk = json.trunk;
    const data = {
        trunk: trunk.map((commit) => 
        // TODO: sort out EncodedCommit vs Commit, and make this type check without `as`.
        decodeCommit(changeCodec, revisionTagCodec, commit, {
            originatorId: commit.sessionId,
            idCompressor: context.idCompressor,
            revision: undefined,
            isSummary: context.isSummary,
            healUnresolvableIdentifiersOnDecode: context.healUnresolvableIdentifiersOnDecode,
            sharedObjectId: context.sharedObjectId,
        })),
        peerLocalBranches: new Map(mapIterable(json.peers, ([sessionId, branch]) => [
            sessionId,
            {
                base: revisionTagCodec.decode(branch.base, {
                    originatorId: sessionId,
                    idCompressor: context.idCompressor,
                    revision: undefined,
                    isSummary: context.isSummary,
                }),
                commits: branch.commits.map((commit) => 
                // TODO: sort out EncodedCommit vs Commit, and make this type check without `as`.
                decodeCommit(changeCodec, revisionTagCodec, commit, {
                    originatorId: commit.sessionId,
                    idCompressor: context.idCompressor,
                    revision: undefined,
                    isSummary: context.isSummary,
                    healUnresolvableIdentifiersOnDecode: context.healUnresolvableIdentifiersOnDecode,
                    sharedObjectId: context.sharedObjectId,
                })),
            },
        ])),
    };
    if (json.session !== undefined) {
        data.session = json.session;
    }
    if (json.name !== undefined) {
        data.name = json.name;
    }
    if (json.author !== undefined) {
        data.author = json.author;
    }
    if (json.id !== undefined) {
        assert(originatorId !== undefined, 0xc63 /* Cannot decode branch id without originatorId */);
        data.id = decodeBranchId(context.idCompressor, json.id, { originatorId });
    }
    if (json.base !== undefined) {
        assert(originatorId !== undefined, 0xc64 /* Cannot decode branch base without originatorId */);
        data.base = revisionTagCodec.decode(json.base, {
            originatorId,
            idCompressor: context.idCompressor,
            revision: undefined,
            isSummary: context.isSummary,
        });
    }
    return data;
}
//# sourceMappingURL=editManagerCodecsCommons.js.map