/*!
 * 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 { SummaryTreeBuilder } from "@fluidframework/runtime-utils/internal";
import { schemaDataIsEmpty, } from "../../core/index.js";
import { encodeRepo } from "./codec.js";
const schemaStringKey = "SchemaString";
/**
 * Provides methods for summarizing and loading a schema repository.
 */
export 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 SummaryTreeBuilder();
        const fullTree = props.fullTree ?? false;
        if (!fullTree &&
            incrementalSummaryContext !== undefined &&
            this.schemaIndexLastChangedSeq !== undefined &&
            incrementalSummaryContext.latestSummarySequenceNumber >= this.schemaIndexLastChangedSeq) {
            builder.addHandle(schemaStringKey, 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.
        assert(schemaDataIsEmpty(this.schema), 0x3da /* there should not already be stored schema when loading stored schema */);
        const schemaString = 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;
    }
}
/**
 * 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.
 */
export function encodeTreeSchema(schema, writeVersion) {
    return encodeRepo(schema, writeVersion);
}
//# sourceMappingURL=schemaSummarizer.js.map