/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { assert } from "@fluidframework/core-utils/internal";
import { SummaryTreeBuilder } from "@fluidframework/runtime-utils/internal";
import { UsageError } from "@fluidframework/telemetry-utils/internal";
import { readAndParseSnapshotBlob } from "../util/index.js";
import { summarizablesMetadataKey, } from "./summaryTypes.js";
/**
 * Utility for implementing {@link Summarizable}s classes with versioning.
 * It handles versioning of summaries - writing version metadata to summaries
 * and checking version compatibility when loading.
 */
export class VersionedSummarizer {
    constructor(
    /** {@link Summarizable.key} */
    key, 
    /** The format version of the summary to write in the summary metadata. */
    writeVersion, 
    /** The set of supported versions that a summary can have for this summarizer to load it. */
    supportedVersions, 
    /**
     * Whether to support loading summaries before versioning was added, i.e., summaries without metadata blob.
     * @remarks
     * This version may not be supported if the support for the version before metadata blob was dropped.
     * In that case, this will not be present in `supportedVersions` and an error will be thrown during load.
     */
    supportPreVersioningFormat) {
        this.key = key;
        this.writeVersion = writeVersion;
        this.supportedVersions = supportedVersions;
        this.supportPreVersioningFormat = supportPreVersioningFormat;
        assert(this.supportedVersions.has(this.writeVersion), 0xca6 /* Unsupported write version requested. */, () => `Write version ${this.writeVersion} requested but not supported with key ${key}.`);
    }
    summarize(props) {
        const builder = new SummaryTreeBuilder();
        const metadata = {
            version: this.writeVersion,
        };
        builder.addBlob(summarizablesMetadataKey, props.stringify(metadata));
        this.summarizeInternal({ ...props, builder });
        return builder.getSummaryTree();
    }
    async load(services, parse) {
        let version;
        if (await services.contains(summarizablesMetadataKey)) {
            const metadata = (await readAndParseSnapshotBlob(summarizablesMetadataKey, services, (contents) => parse(contents)));
            version = metadata.version;
            if (!this.supportedVersions.has(version)) {
                throw new UsageError(`Cannot read version ${version} of shared tree summary.`);
            }
        }
        else if (!this.supportPreVersioningFormat) {
            throw new UsageError(`Cannot read summary without versioning for shared tree summary.`);
        }
        await this.loadInternal(services, parse, version);
    }
}
//# sourceMappingURL=versionedSummarizer.js.map