"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.encodeTreeSchema = exports.SchemaSummarizer = void 0;
const client_utils_1 = require("@fluid-internal/client-utils");
const internal_1 = require("@fluidframework/core-utils/internal");
const driver_definitions_1 = require("@fluidframework/driver-definitions");
const internal_2 = require("@fluidframework/runtime-utils/internal");
const index_js_1 = require("../../core/index.js");
const codec_js_1 = require("./codec.js");
const schemaStringKey = "SchemaString";
/**
 * Provides methods for summarizing and loading a schema repository.
 */
class SchemaSummarizer {
    constructor(schema, collabWindow, codec) {
        this.schema = schema;
        this.codec = codec;
        this.key = "Schema";
        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();
        });
    }
    summarize(props) {
        const incrementalSummaryContext = props.incrementalSummaryContext;
        const builder = new internal_2.SummaryTreeBuilder();
        const fullTree = props.fullTree ?? false;
        if (!fullTree &&
            incrementalSummaryContext !== undefined &&
            this.schemaIndexLastChangedSeq !== undefined &&
            incrementalSummaryContext.latestSummarySequenceNumber >= this.schemaIndexLastChangedSeq) {
            builder.addHandle(schemaStringKey, driver_definitions_1.SummaryType.Blob, `${incrementalSummaryContext.summaryPath}/${schemaStringKey}`);
        }
        else {
            const dataString = JSON.stringify(this.codec.encode(this.schema));
            builder.addBlob(schemaStringKey, dataString);
        }
        return builder.getSummaryTree();
    }
    async load(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.
        (0, internal_1.assert)((0, index_js_1.schemaDataIsEmpty)(this.schema), 0x3da /* there should not already be stored schema when loading stored schema */);
        const schemaString = (0, client_utils_1.bufferToString)(schemaBuffer, "utf-8");
        // 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;
    }
}
exports.SchemaSummarizer = SchemaSummarizer;
/**
 * Dumps schema into a deterministic JSON compatible semi-human readable format.
 *
 * @remarks
 * This can be used to help inspect schema for debugging, and to save a snapshot of schema to help detect and review changes to an applications schema.
 */
function encodeTreeSchema(schema, writeVersion) {
    return (0, codec_js_1.encodeRepo)(schema, writeVersion);
}
exports.encodeTreeSchema = encodeTreeSchema;
//# sourceMappingURL=schemaSummarizer.js.map