/*!
 * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
 * Licensed under the MIT License.
 */
import { strict as assert, fail } from "assert";
import { Type } from "@sinclair/typebox";
import { DecoderContext, decode, readStreamIdentifier,
// eslint-disable-next-line import/no-internal-modules
 } from "../../../../feature-libraries/chunked-forest/codec/chunkDecodingGeneric.js";
import { EncodedFieldBatchGeneric,
// eslint-disable-next-line import/no-internal-modules
 } from "../../../../feature-libraries/chunked-forest/codec/formatGeneric.js";
import { getChecked, readStreamNumber,
// eslint-disable-next-line import/no-internal-modules
 } from "../../../../feature-libraries/chunked-forest/codec/chunkCodecUtilities.js";
import { ReferenceCountedBase } from "../../../../util/index.js";
import { DiscriminatedUnionDispatcher, unionOptions } from "../../../../codec/index.js";
const Constant = Type.Literal(0);
const StringShape = Type.String();
const EncodedChunkShape = Type.Object({
    a: Type.Optional(Constant),
    b: Type.Optional(StringShape),
}, unionOptions);
const version = 1.0;
const EncodedFieldBatch = EncodedFieldBatchGeneric(version, EncodedChunkShape);
class TestChunk1 extends ReferenceCountedBase {
    constructor(value) {
        super();
        this.value = value;
        this.topLevelLength = 1;
    }
    clone() {
        return new TestChunk1(this.value);
    }
    cursor() {
        fail("not implemented");
    }
    dispose() { }
}
class TestChunk2 extends ReferenceCountedBase {
    constructor(value) {
        super();
        this.value = value;
        this.topLevelLength = 1;
    }
    clone() {
        return new TestChunk2(this.value);
    }
    cursor() {
        fail("not implemented");
    }
    dispose() { }
}
const decoderLibrary = new DiscriminatedUnionDispatcher({
    a(shape, cache) {
        return {
            decode(decoders, stream) {
                return new TestChunk2(readStreamNumber(stream));
            },
        };
    },
    b(shape, cache) {
        return {
            decode(decoders, stream) {
                return new TestChunk1(shape);
            },
        };
    },
});
const rootDecoder = {
    decode(decoders, stream) {
        const shape = readStreamNumber(stream);
        const decoder = getChecked(decoders, shape);
        return decoder.decode(decoders, stream);
    },
};
describe("chunkDecodingGeneric", () => {
    it("DecoderContext", () => {
        const cache = new DecoderContext(["a", "b"], []);
        assert.equal(cache.identifier("X"), "X");
        assert.equal(cache.identifier(0), "a");
        assert.equal(cache.identifier(1), "b");
    });
    it("readStreamIdentifier", () => {
        const cache = new DecoderContext(["a", "b"], []);
        const stream = { data: ["X", 0, 1], offset: 0 };
        assert.equal(readStreamIdentifier(stream, cache), "X");
        assert.equal(stream.offset, 1);
        assert.equal(readStreamIdentifier(stream, cache), "a");
        assert.equal(stream.offset, 2);
        assert.equal(readStreamIdentifier(stream, cache), "b");
        assert.equal(stream.offset, 3);
    });
    it("decode: constant shape", () => {
        const encoded = {
            version,
            identifiers: [],
            shapes: [{ a: 0 }],
            data: [[0, 5]],
        };
        const cache = new DecoderContext(encoded.identifiers, encoded.shapes);
        const chunks = decode(decoderLibrary, cache, encoded, rootDecoder);
        assert(chunks.length === 1);
        const chunk = chunks[0];
        assert(chunk instanceof TestChunk2);
        assert.equal(chunk.value, 5);
    });
    it("decode: flexible shape", () => {
        const encoded = {
            version,
            identifiers: [],
            shapes: [{ b: "content" }],
            data: [[0]],
        };
        const cache = new DecoderContext(encoded.identifiers, encoded.shapes);
        const chunks = decode(decoderLibrary, cache, encoded, rootDecoder);
        assert(chunks.length === 1);
        const chunk = chunks[0];
        assert(chunk instanceof TestChunk1);
        assert.equal(chunk.value, "content");
    });
});
//# sourceMappingURL=chunkDecodingGeneric.spec.js.map