/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { strict as assert } from "assert";
import { join as pathJoin } from "path";
import { makeRandom } from "@fluid-private/stochastic-test-utils";
import { createIdCompressor, deserializeIdCompressor, } from "@fluidframework/id-compressor";
import { moveToDetachedField, clonePath, forEachNodeInSubtree, } from "../../../core/index.js";
import { FieldKinds, FlexFieldSchema, intoStoredSchema, } from "../../../feature-libraries/index.js";
import { SchemaBuilder, leaf } from "../../../domains/index.js";
import { expectEqualPaths } from "../../utils.js";
const builder = new SchemaBuilder({ scope: "tree2fuzz", libraries: [leaf.library] });
export const fuzzNode = builder.objectRecursive("node", {
    requiredChild: FlexFieldSchema.createUnsafe(FieldKinds.required, [
        () => fuzzNode,
        ...leaf.primitives,
    ]),
    optionalChild: FlexFieldSchema.createUnsafe(FieldKinds.optional, [
        () => fuzzNode,
        ...leaf.primitives,
    ]),
    sequenceChildren: FlexFieldSchema.createUnsafe(FieldKinds.sequence, [
        () => fuzzNode,
        ...leaf.primitives,
    ]),
});
export const fuzzSchema = builder.intoSchema(fuzzNode.objectNodeFieldsObject.optionalChild);
export const onCreate = (tree) => {
    tree.checkout.updateSchema(intoStoredSchema(fuzzSchema));
};
/**
 * Asserts that each anchor in `anchors` points to a node in `view` holding the provided value.
 * If `checkPaths` is provided, also asserts the located node has the provided path.
 */
export function validateAnchors(view, anchors, checkPaths) {
    const cursor = view.forest.allocateCursor();
    for (const [anchor, [path, value]] of anchors) {
        const result = view.forest.tryMoveCursorToNode(anchor, cursor);
        assert.equal(result, 1 /* TreeNavigationResult.Ok */);
        assert.equal(cursor.value, value);
        if (checkPaths) {
            const actualPath = view.locate(anchor);
            expectEqualPaths(actualPath, path);
        }
    }
    cursor.free();
}
export function createAnchors(tree) {
    const anchors = new Map();
    const cursor = tree.forest.allocateCursor();
    moveToDetachedField(tree.forest, cursor);
    forEachNodeInSubtree(cursor, (c) => {
        const anchor = c.buildAnchor();
        const path = tree.locate(anchor);
        assert(path !== undefined);
        return anchors.set(anchor, [clonePath(path), c.value]);
    });
    cursor.free();
    return anchors;
}
export function isRevertibleSharedTreeView(s) {
    return s.undoStack !== undefined;
}
export const failureDirectory = pathJoin(__dirname, "../../../../src/test/shared-tree/fuzz/failures");
export const createOrDeserializeCompressor = (sessionId, summary) => {
    return summary === undefined
        ? createIdCompressor(sessionId)
        : deserializeIdCompressor(summary, sessionId);
};
export const deterministicIdCompressorFactory = (seed) => {
    const random = makeRandom(seed);
    return (summary) => {
        const sessionId = random.uuid4();
        return createOrDeserializeCompressor(sessionId, summary);
    };
};
//# sourceMappingURL=fuzzUtils.js.map