"use strict";
/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.schemaDataIsEmpty = exports.TreeStoredSchemaRepository = void 0;
const sorted_btree_es6_1 = require("@tylerbu/sorted-btree-es6");
const client_utils_1 = require("@fluid-internal/client-utils");
const index_js_1 = require("../../util/index.js");
const schema_js_1 = require("./schema.js");
/**
 * Mutable TreeStoredSchema repository.
 */
class TreeStoredSchemaRepository {
    /**
     * Copies in the provided schema. If `data` is an TreeStoredSchemaRepository, it will be cheap-cloned.
     * Otherwise, it will be deep-cloned.
     *
     * We might not want to store schema in maps long term, as we might want a way to reserve a
     * large space of schema IDs within a schema.
     * The way mapFields has been structured mitigates the need for this, but it still might be useful.
     *
     * (ex: someone using data as field identifiers might want to
     * reserve all fields identifiers starting with "foo." to have a specific schema).
     * Combined with support for such namespaces in the allowed sets in the schema objects,
     * that might provide a decent alternative to mapFields (which is a bit odd).
     */
    constructor(data) {
        this._events = (0, client_utils_1.createEmitter)();
        this.events = this._events;
        if (data === undefined) {
            this.rootFieldSchemaData = schema_js_1.storedEmptyFieldSchema;
            this.nodeSchemaData = new sorted_btree_es6_1.BTree([], index_js_1.compareStrings);
        }
        else {
            if (data instanceof TreeStoredSchemaRepository) {
                this.rootFieldSchemaData = data.rootFieldSchema;
                this.nodeSchemaData = data.nodeSchemaData.clone();
            }
            else {
                this.rootFieldSchemaData = data.rootFieldSchema;
                this.nodeSchemaData = cloneNodeSchemaData(data.nodeSchema);
            }
        }
    }
    get nodeSchema() {
        // Btree implements iterator, but not in a type-safe way
        return this.nodeSchemaData;
    }
    get rootFieldSchema() {
        return this.rootFieldSchemaData;
    }
    apply(newSchema) {
        this._events.emit("beforeSchemaChange", newSchema);
        const clone = new TreeStoredSchemaRepository(newSchema);
        // In the future, we could use btree's delta functionality to do a more efficient update
        this.rootFieldSchemaData = clone.rootFieldSchemaData;
        this.nodeSchemaData = clone.nodeSchemaData;
        this._events.emit("afterSchemaChange", newSchema);
    }
    clone() {
        return new TreeStoredSchemaRepository(this);
    }
}
exports.TreeStoredSchemaRepository = TreeStoredSchemaRepository;
function schemaDataIsEmpty(data) {
    return data.nodeSchema.size === 0;
}
exports.schemaDataIsEmpty = schemaDataIsEmpty;
function cloneNodeSchemaData(nodeSchema) {
    // Schema objects are immutable (unlike stored schema repositories), so this shallow copy is fine.
    const entries = [
        ...nodeSchema.entries(),
    ];
    return new sorted_btree_es6_1.BTree(entries, index_js_1.compareStrings);
}
//# sourceMappingURL=storedSchemaRepository.js.map