/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { assert } from "@fluidframework/core-utils/internal";
import { SummaryType } from "@fluidframework/driver-definitions";
import { blobHeadersBlobName as blobNameForBlobHeaders, readAndParse, } from "@fluidframework/driver-utils/internal";
import { channelsTreeName, gcTreeKey, } from "@fluidframework/runtime-definitions/internal";
export function getAttributesFormatVersion(attributes) {
    if (attributes.summaryFormatVersion) {
        /**
         * Version 2+: Introduces .channels trees for isolation of
         * channel trees from data store objects.
         */
        return attributes.summaryFormatVersion;
    }
    else if (attributes.snapshotFormatVersion === "0.1") {
        /**
         * Version 1: from this version the pkg within the data store
         * attributes blob is a JSON array rather than a string.
         */
        return 1;
    }
    /**
     * Version 0: format version is missing from summary.
     * This indicates it is an older version.
     */
    return 0;
}
export function hasIsolatedChannels(attributes) {
    return !!attributes.summaryFormatVersion && !attributes.disableIsolatedChannels;
}
/**
 * Extracts the properties from an ISequencedDocumentMessage as defined by ISummaryMetadataMessage. This message is
 * added to the metadata blob in summary.
 */
export const extractSummaryMetadataMessage = (message) => message === undefined
    ? undefined
    : {
        clientId: message.clientId,
        clientSequenceNumber: message.clientSequenceNumber,
        minimumSequenceNumber: message.minimumSequenceNumber,
        referenceSequenceNumber: message.referenceSequenceNumber,
        sequenceNumber: message.sequenceNumber,
        timestamp: message.timestamp,
        type: message.type,
    };
export function getMetadataFormatVersion(metadata) {
    /**
     * Version 2+: Introduces runtime sequence number for data verification.
     *
     * Version 1+: Introduces .metadata blob and .channels trees for isolation of
     * data store trees from container-level objects.
     * Also introduces enableGC option stored in the summary.
     *
     * Version 0: metadata blob missing; format version is missing from summary.
     * This indicates it is an older version.
     */
    return metadata?.summaryFormatVersion ?? 0;
}
export const aliasBlobName = ".aliases";
export const metadataBlobName = ".metadata";
export const chunksBlobName = ".chunks";
export const electedSummarizerBlobName = ".electedSummarizer";
export const blobsTreeName = ".blobs";
export const idCompressorBlobName = ".idCompressor";
export const blobHeadersBlobName = blobNameForBlobHeaders;
export function rootHasIsolatedChannels(metadata) {
    return !!metadata && !metadata.disableIsolatedChannels;
}
export const protocolTreeName = ".protocol";
/**
 * List of tree IDs at the container level which are reserved.
 * This is for older versions of summaries that do not yet have an
 * isolated data stores namespace. Without the namespace, this must
 * be used to prevent name collisions with data store IDs.
 */
export const nonDataStorePaths = [
    protocolTreeName,
    ".logTail",
    ".serviceProtocol",
    blobsTreeName,
    gcTreeKey,
    idCompressorBlobName,
];
export const dataStoreAttributesBlobName = ".component";
/**
 * Modifies summary tree and stats to put tree under .channels tree.
 *
 * @param summarizeResult - Summary tree and stats to modify
 *
 * @example
 *
 * Converts from:
 *
 * ```typescript
 * {
 *     type: SummaryType.Tree,
 *     tree: { a: {...}, b: {...}, c: {...} },
 * }
 * ```
 *
 * to:
 *
 * ```typescript
 * {
 *     type: SummaryType.Tree,
 *     tree: {
 *         ".channels": {
 *             type: SummaryType.Tree,
 *             tree: { a: {...}, b: {...}, c: {...} }
 *         },
 *     },
 * }
 * ```
 *
 * And adds +1 to treeNodeCount in stats.
 */
export function wrapSummaryInChannelsTree(summarizeResult) {
    summarizeResult.summary = {
        type: SummaryType.Tree,
        tree: { [channelsTreeName]: summarizeResult.summary },
    };
    summarizeResult.stats.treeNodeCount++;
}
export async function getFluidDataStoreAttributes(storage, snapshot) {
    const attributes = await readAndParse(storage, snapshot.blobs[dataStoreAttributesBlobName]);
    // Use the snapshotFormatVersion to determine how the pkg is encoded in the snapshot.
    // For snapshotFormatVersion = "0.1" (1) or above, pkg is jsonified, otherwise it is just a string.
    // However the feature of loading a detached container from snapshot, is added when the
    // snapshotFormatVersion is at least "0.1" (1), so we don't expect it to be anything else.
    const formatVersion = getAttributesFormatVersion(attributes);
    assert(formatVersion > 0, 0x1d5 /* Invalid snapshot format version */);
    return attributes;
}
//# sourceMappingURL=summaryFormat.js.map