/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { bufferToString } from "@fluid-internal/client-utils";
import { assert } from "@fluidframework/core-utils/internal";
import { SummaryType } from "@fluidframework/driver-definitions";
import { schemaDataIsEmpty, } from "../../core/index.js";
import { VersionedSummarizer, } from "../../shared-tree-core/index.js";
export const schemaStringKey = "SchemaString";
/**
 * The versions for the schema summary format.
 */
export var SchemaSummaryFormatVersion;
(function (SchemaSummaryFormatVersion) {
    /**
     * This version represents summary format before summary versioning was introduced.
     */
    SchemaSummaryFormatVersion[SchemaSummaryFormatVersion["v1"] = 1] = "v1";
    /**
     * This version adds metadata to the summary. This is backward compatible with version 1.
     */
    SchemaSummaryFormatVersion[SchemaSummaryFormatVersion["v2"] = 2] = "v2";
    /**
     * The latest version of the summary. Must be updated when a new version is added.
     */
    SchemaSummaryFormatVersion[SchemaSummaryFormatVersion["vLatest"] = 2] = "vLatest";
})(SchemaSummaryFormatVersion || (SchemaSummaryFormatVersion = {}));
const supportedVersions = new Set([
    1 /* SchemaSummaryFormatVersion.v1 */,
    2 /* SchemaSummaryFormatVersion.v2 */,
]);
/**
 * Returns the summary version to use as per the given minimum version for collab.
 */
function minVersionToSchemaSummaryFormatVersion(version) {
    // Currently, version 2 is written which adds metadata blob to the summary.
    return 2 /* SchemaSummaryFormatVersion.v2 */;
}
/**
 * Provides methods for summarizing and loading a schema repository.
 */
export class SchemaSummarizer extends VersionedSummarizer {
    constructor(schema, collabWindow, codec, minVersionForCollab) {
        super("Schema", minVersionToSchemaSummaryFormatVersion(minVersionForCollab), supportedVersions, true /* supportPreVersioningFormat */);
        this.schema = schema;
        this.codec = codec;
        this.schema.events.on("afterSchemaChange", () => {
            // Invalidate the cache, as we need to regenerate the blob if the schema changes
            // We are assuming that schema changes from remote ops are valid, as we are in a summarization context.
            this.schemaIndexLastChangedSeq = collabWindow.getCurrentSeq();
        });
    }
    summarizeInternal(props) {
        const { builder, incrementalSummaryContext, stringify, fullTree = false } = props;
        if (!fullTree &&
            incrementalSummaryContext !== undefined &&
            this.schemaIndexLastChangedSeq !== undefined &&
            incrementalSummaryContext.latestSummarySequenceNumber >= this.schemaIndexLastChangedSeq) {
            builder.addHandle(schemaStringKey, SummaryType.Blob, `${incrementalSummaryContext.summaryPath}/${schemaStringKey}`);
        }
        else {
            const dataString = stringify(this.codec.encode(this.schema));
            builder.addBlob(schemaStringKey, dataString);
        }
    }
    async loadInternal(services, parse) {
        const schemaBuffer = await services.readBlob(schemaStringKey);
        // After the awaits, validate that the schema is in a clean state.
        // This detects any schema that could have been accidentally added through
        // invalid means and are about to be overwritten.
        assert(schemaDataIsEmpty(this.schema), 0x3da /* there should not already be stored schema when loading stored schema */);
        const schemaString = bufferToString(schemaBuffer, "utf8");
        // Currently no Fluid handles are used, so just use JSON.parse.
        const decoded = this.codec.decode(JSON.parse(schemaString));
        this.schema.apply(decoded);
        this.schemaIndexLastChangedSeq = 0;
    }
}
//# sourceMappingURL=schemaSummarizer.js.map