"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.VersionedSummarizer = void 0;
const internal_1 = require("@fluidframework/core-utils/internal");
const internal_2 = require("@fluidframework/runtime-utils/internal");
const internal_3 = require("@fluidframework/telemetry-utils/internal");
const index_js_1 = require("../util/index.js");
const summaryTypes_js_1 = require("./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.
 */
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;
        (0, internal_1.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 internal_2.SummaryTreeBuilder();
        const metadata = {
            version: this.writeVersion,
        };
        builder.addBlob(summaryTypes_js_1.summarizablesMetadataKey, props.stringify(metadata));
        this.summarizeInternal({ ...props, builder });
        return builder.getSummaryTree();
    }
    async load(services, parse) {
        let version;
        if (await services.contains(summaryTypes_js_1.summarizablesMetadataKey)) {
            const metadata = (await (0, index_js_1.readAndParseSnapshotBlob)(summaryTypes_js_1.summarizablesMetadataKey, services, (contents) => parse(contents)));
            version = metadata.version;
            if (!this.supportedVersions.has(version)) {
                throw new internal_3.UsageError(`Cannot read version ${version} of shared tree summary.`);
            }
        }
        else if (!this.supportPreVersioningFormat) {
            throw new internal_3.UsageError(`Cannot read summary without versioning for shared tree summary.`);
        }
        await this.loadInternal(services, parse, version);
    }
}
exports.VersionedSummarizer = VersionedSummarizer;
//# sourceMappingURL=versionedSummarizer.js.map