/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { strict as assert } from "node:assert";
import { MockFluidDataStoreRuntime } from "@fluidframework/test-runtime-utils";
import { unreachableCase } from "@fluidframework/core-utils";
import { SchemaFactory, TreeConfiguration, } from "../../simple-tree/index.js";
import { TreeFactory } from "../../treeFactory.js";
import { enumFromStrings, typedObjectValues, adaptEnum,
// eslint-disable-next-line import/no-internal-modules
 } from "../../simple-tree/schemaCreationUtilities.js";
import { testIdCompressor } from "../utils.js";
const schema = new SchemaFactory("test");
describe("schemaCreationUtilities", () => {
    it("enum type switch", () => {
        const Mode = enumFromStrings(schema, ["Fun", "Cool", "Bonus"]);
        class Parent extends schema.object("Parent", { mode: Object.values(Mode) }) {
        }
        const config = new TreeConfiguration(Parent, () => new Parent({
            mode: new Mode.Bonus({}),
        }));
        const factory = new TreeFactory({});
        const tree = factory.create(new MockFluidDataStoreRuntime({ idCompressor: testIdCompressor }), "tree");
        const view = tree.schematize(config);
        const mode = view.root.mode;
        switch (true) {
            case mode instanceof Mode.Bonus: {
                // This one runs
                break;
            }
            case mode instanceof Mode.Fun: {
                assert.fail();
            }
            case mode instanceof Mode.Cool: {
                assert.fail();
            }
            default:
                assert.fail();
        }
    });
    it("enumFromStrings example", () => {
        const schemaFactory = new SchemaFactory("x");
        const Mode = enumFromStrings(schemaFactory, ["Fun", "Cool"]);
        const nodeFromString = Mode("Fun");
        const nodeFromSchema = new Mode.Fun();
        // eslint-disable-next-line no-constant-condition
        if (false) {
            // Check this compiles, but don't run it since node is unhydrated
            const nameFromNode = nodeFromSchema.value;
        }
        class Parent extends schemaFactory.object("Parent", { mode: typedObjectValues(Mode) }) {
        }
    });
    it("adaptEnum example", () => {
        const schemaFactory = new SchemaFactory("x");
        let Mode;
        (function (Mode) {
            Mode["a"] = "A";
            Mode["b"] = "B";
        })(Mode || (Mode = {}));
        const ModeNodes = adaptEnum(schema, Mode);
        const nodeFromString = ModeNodes(Mode.a);
        const nodeFromSchema = new ModeNodes.a();
        // eslint-disable-next-line no-constant-condition
        if (false) {
            // Check this compiles, but don't run it since node is unhydrated
            const nameFromNode = nodeFromSchema.value;
        }
        class Parent extends schemaFactory.object("Parent", {
            mode: typedObjectValues(ModeNodes),
        }) {
        }
        const _test1 = new ModeNodes.a();
        // @ts-expect-error Incompatible enums types should not be assignable.
        const _test2 = new ModeNodes.b();
    });
    it("enum value switch", () => {
        const Mode = enumFromStrings(schema, ["Fun", "Cool", "Bonus"]);
        class Parent extends schema.object("Parent", { mode: typedObjectValues(Mode) }) {
        }
        const config = new TreeConfiguration(Parent, () => new Parent({
            mode: new Mode.Bonus({}),
        }));
        const factory = new TreeFactory({});
        const tree = factory.create(new MockFluidDataStoreRuntime({ idCompressor: testIdCompressor }), "tree");
        const view = tree.schematize(config);
        const mode = view.root.mode;
        switch (mode.value) {
            case "Fun": {
                assert.fail();
            }
            case "Cool": {
                assert.fail();
            }
            case "Bonus": {
                // This one runs
                break;
            }
            default:
                unreachableCase(mode.value);
        }
    });
    it("enum interop - enumFromStrings", () => {
        const factory = new TreeFactory({});
        let Day;
        (function (Day) {
            Day["Today"] = "Today";
            Day["Tomorrow"] = "Tomorrow";
        })(Day || (Day = {}));
        const DayNodes = enumFromStrings(schema, typedObjectValues(Day));
        const tree = factory.create(new MockFluidDataStoreRuntime({ idCompressor: testIdCompressor }), "tree");
        const day = Day.Today;
        const view = tree.schematize(new TreeConfiguration(typedObjectValues(DayNodes), () => DayNodes(day)));
        switch (view.root.value) {
            case Day.Today: {
                // This one runs
                break;
            }
            case Day.Tomorrow: {
                assert.fail();
            }
            default:
                unreachableCase(view.root.value);
        }
    });
    it("enum interop - adaptEnum", () => {
        const factory = new TreeFactory({});
        let Day;
        (function (Day) {
            Day["Today"] = "today";
            Day["Tomorrow"] = "tomorrow";
        })(Day || (Day = {}));
        const DayNodes = adaptEnum(schema, Day);
        const tree = factory.create(new MockFluidDataStoreRuntime({ idCompressor: testIdCompressor }), "tree");
        // Can convert enum to unhydrated node:
        const x = DayNodes(Day.Today);
        // Can construct unhydrated node from enum's key:
        const y = new DayNodes.Today({});
        const view = tree.schematize(new TreeConfiguration(typedObjectValues(DayNodes), () => DayNodes(Day.Today)));
        switch (view.root.value) {
            case Day.Today: {
                break;
            }
            case Day.Tomorrow: {
                assert.fail();
            }
            default:
                unreachableCase(view.root);
        }
    });
});
//# sourceMappingURL=schemaCreationUtilities.spec.js.map