import { makeAppObjectRepo } from "@vived/core";
import { Angle, Quaternion, Vector3 } from "@vived/core";
import { OverlayColorEnums } from "../../OverlayColor";
import { makeStateMachineEntity } from "../../StateMachine";
import { makeLandmarkGlobals, } from "../Entities/LandmarkGlobals";
import { makeLandmarkRepoEntity } from "../Entities/LandmarkRepo";
import { SerializeLandmarks, } from "./SerializeLandmarks";
function makeDto(id, parentID) {
    const q = Quaternion.FromYawPitchRoll(Angle.FromDegrees(10), Angle.FromDegrees(20), Angle.FromDegrees(30));
    const dto = {
        id,
        position: new Vector3(1, 2, 3).dto,
        size: 5,
        parentID,
        rotation: q.dto,
        label: "Callout Label",
        defaultLabel: "Custom Label",
        color: OverlayColorEnums.BLUE,
    };
    return dto;
}
function makeTestRig() {
    const appObjects = makeAppObjectRepo();
    const stateMachineAo = appObjects.getOrCreate("stateMachine");
    const stateMachine = makeStateMachineEntity(stateMachineAo);
    const registerSpy = jest.spyOn(stateMachine, "registerSerializedSystem");
    makeLandmarkGlobals(appObjects.getOrCreate("LandmarkGlobals"));
    const serializer = new SerializeLandmarks(appObjects.getOrCreate("Landmark Serializer"));
    const repo1 = makeLandmarkRepoEntity(appObjects.getOrCreate("Repo1"));
    const landmark1 = repo1.createLandmark("landmark1");
    const repo2 = makeLandmarkRepoEntity(appObjects.getOrCreate("Repo2"));
    const landmark2 = repo2.createLandmark("landmark2");
    return {
        appObjects,
        serializer,
        repo1,
        repo2,
        landmark1,
        landmark2,
        registerSpy,
    };
}
describe("Serialize Landmarks Test", () => {
    it("Registers with the Serialized System on construction", () => {
        const { registerSpy, serializer } = makeTestRig();
        expect(registerSpy).toHaveBeenCalledWith(serializer);
    });
    it("Returns all landmarks", () => {
        const { serializer, landmark1, landmark2 } = makeTestRig();
        const state = serializer.getSystemState();
        expect(state.landmarks.length).toEqual(2);
        expect(state.landmarks).toEqual([landmark1.data, landmark2.data]);
    });
    it("Clears all existing landmarks if the default state is applied", () => {
        const { serializer, repo1, repo2 } = makeTestRig();
        expect(repo1.getAll().length).toEqual(1);
        expect(repo2.getAll().length).toEqual(1);
        serializer.applyDefaultState();
        expect(repo1.getAll().length).toEqual(0);
        expect(repo2.getAll().length).toEqual(0);
    });
    it("Disposes all existing landmarks if the default state is applied", () => {
        const { serializer, landmark1, landmark2 } = makeTestRig();
        landmark1.appObject.dispose = jest.fn();
        landmark2.appObject.dispose = jest.fn();
        serializer.applyDefaultState();
        expect(landmark1.appObject.dispose).toHaveBeenCalled();
        expect(landmark1.appObject.dispose).toHaveBeenCalled();
    });
    it("Defaults and warns if the version is not supported", () => {
        const { serializer } = makeTestRig();
        serializer.warn = jest.fn();
        serializer.applyDefaultState = jest.fn();
        serializer.applySystemState({ foo: "bar" }, -1);
        expect(serializer.applyDefaultState).toHaveBeenCalled();
        expect(serializer.warn).toHaveBeenCalled();
    });
    it("Defaults and warns if the state is bungled", () => {
        const { serializer } = makeTestRig();
        serializer.warn = jest.fn();
        serializer.applyDefaultState = jest.fn();
        serializer.applySystemState({ foo: "bar" }, 1);
        expect(serializer.applyDefaultState).toHaveBeenCalled();
        expect(serializer.warn).toHaveBeenCalled();
    });
    it("Create a new landmark entity for existing repo", () => {
        const { serializer, repo1 } = makeTestRig();
        const data = makeDto("newLandmark", repo1.appObject.id);
        const state = {
            landmarks: [data],
        };
        expect(repo1.hasForAppObject("newLandmark")).toEqual(false);
        serializer.applySystemState(state, 1);
        expect(repo1.hasForAppObject("newLandmark")).toEqual(true);
    });
    it("Create a new repo", () => {
        const { serializer, appObjects } = makeTestRig();
        const data = makeDto("newLandmark", "newRepoId");
        const state = {
            landmarks: [data],
        };
        expect(appObjects.has("newRepoId")).toEqual(false);
        serializer.applySystemState(state, 1);
        expect(appObjects.has("newRepoId")).toEqual(true);
    });
    it("Removes landmarks that are not in the state", () => {
        const { serializer, repo1, repo2 } = makeTestRig();
        const state = {
            landmarks: [makeDto("aDifferentLandmark", "aDifferentRepo")],
        };
        expect(repo1.getAll().length).toEqual(1);
        expect(repo2.getAll().length).toEqual(1);
        serializer.applySystemState(state, 1);
        expect(repo1.getAll().length).toEqual(0);
        expect(repo2.getAll().length).toEqual(0);
    });
    it("Updates existing landmarks that are in the state", () => {
        const { serializer, landmark1, repo1 } = makeTestRig();
        const spy = jest.spyOn(landmark1, "data", "set");
        const data = makeDto(landmark1.appObject.id, landmark1.parentID);
        const state = {
            landmarks: [data],
        };
        serializer.applySystemState(state, 1);
        expect(spy).toHaveBeenCalledWith(data);
        expect(repo1.getAll().length).toEqual(1);
    });
});
//# sourceMappingURL=SerializeLandmarks.test.js.map