import { test, expect } from '@playwright/test';
import {SimpleGamesystem} from "../../../src/app/project/game-model/gamesystems/SimpleGamesystem";

test.describe('Test SimpleGamesystem', () => {

  test("Create SimpleState", async () => {
    const gamesystem = new SimpleGamesystem();
    let state = gamesystem.createState("Test", "Test2");
    expect(state.stateLabel).toEqual("Test");
    expect(state.stateDescription).toEqual("Test2");
    expect(state.incomingTransitions.length).toEqual(0);
    expect(state.outgoingTransitions.length).toEqual(0);
    expect(gamesystem.states.includes(state)).toBeTruthy();

    state = gamesystem.createState(null, null);
    expect(state).toBeUndefined();
    expect(gamesystem.states.includes(state)).toBeFalsy();

    state = gamesystem.createState(null, "test2");
    expect(state).toBeUndefined()
    expect(gamesystem.states.includes(state)).toBeFalsy();

    state = gamesystem.createState("test2", null);
    expect(state).toBeDefined();
    expect(state.stateLabel).toEqual("test2");
    expect(state.stateDescription).toEqual("");
    expect(gamesystem.states.includes(state)).toBeTruthy();

    state = gamesystem.createState(undefined, "State");
    expect(state).toBeUndefined();
    expect(gamesystem.states.includes(state)).toBeFalsy();

    state = gamesystem.createState("Test3", undefined);
    expect(state).toBeDefined();
    expect(state.stateLabel).toEqual("Test3");
    expect(state.stateDescription).toEqual("");
    expect(gamesystem.states.includes(state)).toBeTruthy();

    state = gamesystem.createState("", "");
    expect(state).toBeDefined();
    expect(state.stateLabel).toEqual("");
    expect(state.stateDescription).toEqual("");
    expect(gamesystem.states.includes(state)).toBeTruthy();

    state = gamesystem.createState("Test3", "");
    expect(state).toBeUndefined();
    expect(gamesystem.states.includes(state)).toBeFalsy();
  })

  test("Create SimpleTransition", async () => {
    const gamesystem = new SimpleGamesystem();
    const startingState = gamesystem.createState("StartingState", "")!;
    const endingState = gamesystem.createState("EndingState", "")!

    let transition = gamesystem.createTransition(startingState, endingState);
    expect(transition).toBeDefined();
    expect(transition.startingState).toEqual(startingState);
    expect(transition.endingState).toEqual(endingState);
    expect(startingState.outgoingTransitions.includes(transition)).toBeTruthy();
    expect(endingState.incomingTransitions.includes(transition)).toBeTruthy();
    expect(gamesystem.transitions.includes(transition)).toBeTruthy();

    transition = gamesystem.createTransition(null, null);
    expect(transition).toBeUndefined();

    transition = gamesystem.createTransition(null, endingState);
    expect(transition).toBeUndefined();

    transition = gamesystem.createTransition(undefined, undefined);
    expect(transition).toBeUndefined();

    transition = gamesystem.createTransition(undefined, endingState);
    expect(transition).toBeUndefined();

    transition = gamesystem.createTransition(startingState, null);
    expect(transition).toBeUndefined();

    transition = gamesystem.createTransition(startingState, undefined);
    expect(transition).toBeUndefined();

    transition = gamesystem.createTransition(startingState, startingState);
    expect(transition).toBeUndefined();

    transition = gamesystem.createTransition(startingState, endingState);
    expect(transition).toBeUndefined();

  })

  test("Remove SimpleState", async () => {
      const gamesystem = new SimpleGamesystem("Test");
      const state1 = gamesystem.createState("State1", "");

      const state1_delete = gamesystem.removeState(state1);
      expect(state1_delete).toBeTruthy();
      expect(gamesystem.states.includes(state1)).toBeFalsy();

      let startingState = gamesystem.createState("Start", "End");
      let endingState = gamesystem.createState("End", "");
      let transition = gamesystem.createTransition(startingState, endingState);
      let result = gamesystem.removeState(startingState);
      expect(result).toBeTruthy();
      expect(gamesystem.states.includes(startingState)).toBeFalsy();
      expect(gamesystem.states.includes(endingState)).toBeTruthy();
      expect(gamesystem.transitions.length).toEqual(0);

      startingState = gamesystem.createState("Start");
      transition = gamesystem.createTransition(startingState, endingState);
      gamesystem.removeState(endingState);
      expect(result).toBeTruthy();
      expect(gamesystem.states.includes(startingState)).toBeTruthy();
      expect(gamesystem.states.includes(endingState)).toBeFalsy();
      expect(gamesystem.transitions.length).toEqual(0);

      endingState = gamesystem.createState("End");
      transition = gamesystem.createTransition(startingState, endingState);
      const testingState = gamesystem.createState("TestingState", "");
      result = gamesystem.removeState(testingState);
      expect(result).toBeTruthy();
      expect(gamesystem.transitions.includes(transition)).toBeTruthy();

      const gamesystem2 = new SimpleGamesystem("test2");
      const state2 = gamesystem2.createState("Test", "");
      result = gamesystem.removeState(state2);
      expect(result).toBeFalsy();

      result = gamesystem.removeState(null);
      expect(result).toBeFalsy();

      result = gamesystem.removeState(undefined);
      expect(result).toBeFalsy();
  })

  test("Remove SimpleTransition", async () => {
      const gamesystem = new SimpleGamesystem("Gamesystem");
      const A = gamesystem.createState("A");
      const B = gamesystem.createState("B");
      let AB = gamesystem.createTransition(A, B);

      let result = gamesystem.removeTransition(AB);
      expect(result).toBeTruthy();
      expect(gamesystem.transitions.includes(AB)).toBeFalsy();

      AB = gamesystem.createTransition(A, B);
      const C = gamesystem.createState("C");
      const D = gamesystem.createState("D");
      let CD = gamesystem.createTransition(C, D);

      result = gamesystem.removeTransition(AB);
      expect(result).toBeTruthy();
      expect(gamesystem.transitions.includes(AB)).toBeFalsy();
      expect(gamesystem.transitions.includes(CD)).toBeTruthy();

      let BA = gamesystem.createTransition(B, A);
      AB = gamesystem.createTransition(A, B);
      result = gamesystem.removeTransition(AB);
      expect(result).toBeTruthy();
      expect(gamesystem.transitions.includes(AB)).toBeFalsy();
      expect(gamesystem.transitions.includes(BA)).toBeTruthy();

      result = gamesystem.removeTransition(AB);
      expect(result).toBeFalsy();

  })
});