"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 core_utils_1 = require("@fluidframework/core-utils");
const runtime_utils_1 = require("@fluidframework/runtime-utils");
const protocol_definitions_1 = require("@fluidframework/protocol-definitions");
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(runtime, schema, options, collabWindow) {
        this.runtime = runtime;
        this.schema = schema;
        this.key = "Schema";
        this.codec = (0, codec_js_1.makeSchemaCodec)(options);
        this.schema.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();
        });
    }
    getAttachSummary(stringify, fullTree, trackState, telemetryContext, incrementalSummaryContext) {
        const builder = new runtime_utils_1.SummaryTreeBuilder();
        if (incrementalSummaryContext !== undefined &&
            this.schemaIndexLastChangedSeq !== undefined &&
            incrementalSummaryContext.latestSummarySequenceNumber >= this.schemaIndexLastChangedSeq) {
            builder.addHandle(schemaStringKey, protocol_definitions_1.SummaryType.Blob, `${incrementalSummaryContext.summaryPath}/indexes/${this.key}/${schemaStringKey}`);
        }
        else {
            const dataString = JSON.stringify(this.codec.encode(this.schema));
            builder.addBlob(schemaStringKey, dataString);
        }
        return builder.getSummaryTree();
    }
    async summarize(stringify, fullTree, trackState, telemetryContext, incrementalSummaryContext) {
        throw new Error("Method not implemented.");
    }
    getGCData(fullGC) {
        // TODO: Properly implement garbage collection. Right now, garbage collection is performed automatically
        // by the code in SharedObject (from which SharedTreeCore extends). The `runtime.uploadBlob` API delegates
        // to the `BlobManager`, which automatically populates the summary with ISummaryAttachment entries for each
        // blob.
        return {
            gcNodes: {},
        };
    }
    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, core_utils_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 but unspecified 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.
 *
 * This format may change across major versions of this package: such changes are considered breaking.
 * Beyond that, no compatibility guarantee is provided for this format: it should never be relied upon to load data, it should only be used for comparing outputs from this function.
 * @privateRemarks
 * This currently uses the schema summary format, but that could be changed to something more human readable (particularly if the encoded format becomes less human readable).
 * This intentionally does not leak the format types in the API.
 * @internal
 */
function encodeTreeSchema(schema) {
    return (0, codec_js_1.encodeRepo)(schema);
}
exports.encodeTreeSchema = encodeTreeSchema;
//# sourceMappingURL=schemaSummarizer.js.map