/*
   * Test method for {@link de.uni.freiburg.iig.telematik.sepia.petrinet.ifnet.RegularIFNetTransition#addGuard(de.invation.code.toval.constraint.AbstractConstraint)}. Try to add various invalid guards.
   */
  @Test
  public void testAddGuard() {
    IFNet sNet = null;
    try {
      sNet = IFNetTestUtil.createSimpleIFNet();
    } catch (ParameterException e) {
      fail("Cannot create SNet");
    }
    RegularIFNetTransition trans = (RegularIFNetTransition) sNet.getTransition("tIn");

    // Try to add an guard before adding a guarddatacontainer
    try {
      NumberConstraint nc = new NumberConstraint("green", NumberOperator.IN_INTERVAL, -1, 1);
      trans.addGuard(nc);
      fail("Guard was added without a GuardDataContainer beeing set.");
    } catch (ParameterException e) {
    }

    // Add the missing guard datacontainer
    TestGuardDataContainer tgdc = new TestGuardDataContainer(sNet.getTokenColors());
    try {
      trans.setGuardDataContainer(tgdc);
    } catch (ParameterException e1) {
      fail("Cannot set GuardDataContainer!");
    }

    // Try to add an guard which contains colors not processed by the transition
    try {
      NumberConstraint nc = new NumberConstraint("pink", NumberOperator.IN_INTERVAL, -1, 1);
      trans.addGuard(nc);
      fail("Guard was added with colors not processed by the transtion");
    } catch (ParameterException e) {
    }

    // Try to add an guard which has no values incommen with the data container
    try {
      NumberConstraint nc = new NumberConstraint("green", NumberOperator.IN_INTERVAL, -1, 1);
      RegularIFNetTransition t0 = (RegularIFNetTransition) sNet.getTransition("t0");
      t0.setGuardDataContainer(tgdc);
      tgdc.removeAttribute("green");
      t0.addGuard(nc);
      fail("Guard was added with colors not contained in the GuardDataContainer");
    } catch (ParameterException e) {
    }

    // Try to add an guard which is not compatible
    try {
      StringConstraint sc = new StringConstraint("green", StringOperator.EQUAL, "fail");

      RegularIFNetTransition t0 = (RegularIFNetTransition) sNet.getTransition("t0");
      t0.setGuardDataContainer(new TestGuardDataContainer(sNet.getTokenColors()));
      tgdc.removeAttribute("green");
      t0.addGuard(sc);
      fail("Guard was added which has values of the wrong type.");
    } catch (ParameterException e) {
    }
  }
  /*
   * Test the clone() method
   */
  @Test
  public void testRegularIFNetTransitionClone() throws ParameterException {
    IFNet sNet = IFNetTestUtil.createSimpleIFNet();
    RegularIFNetTransition t = (RegularIFNetTransition) sNet.getTransition("t0");
    t.setSilent(true);
    // Create an instance of TestGuardDataContainer
    TestGuardDataContainer tgdc = new TestGuardDataContainer(sNet.getTokenColors());
    t.setGuardDataContainer(tgdc);

    RegularIFNetTransition tClone = t.clone();
    assertEquals(t, tClone);
    assertNotSame(t, tClone);
    assertTrue(tClone.isSilent());
    assertEquals(t.getName(), tClone.getName());
    assertEquals(t.getLabel(), tClone.getLabel());
    assertEquals(t.isPlace(), tClone.isPlace());
    assertEquals(t.isDrain(), tClone.isDrain());
    assertEquals(t.isSource(), tClone.isSource());
    assertEquals(t.isTransition(), tClone.isTransition());
    assertEquals(t.getGuards().size(), tClone.getGuards().size());
    assertEquals(t.getGuardDataContainer(), tClone.getGuardDataContainer());
    // assertNotSame(t.getGuardDataContainer(), tClone.getGuardDataContainer());

    // Access modes
    for (Entry<String, Set<AccessMode>> color : t.getAccessModes().entrySet()) {
      assertEquals(color.getValue(), tClone.getAccessModes(color.getKey()));
    }
  }
  /*
   * Test method for {@link de.uni.freiburg.iig.telematik.sepia.petrinet.ifnet.RegularIFNetTransition#checkState()}. Check whether an enabled transition is reported to be enabled and a disable transition to be disabled based on guards
   */
  @Test
  public void testCheckStateGuard() throws ParameterException {

    // Get a simple standard SNet and two of its transitions
    IFNet sNet = IFNetTestUtil.createSimpleIFNet();
    RegularIFNetTransition trans = (RegularIFNetTransition) sNet.getTransition("tIn");

    // create aGuardDataContainer
    TestGuardDataContainer tgdc = new TestGuardDataContainer(sNet.getTokenColors());

    // create two guards
    NumberConstraint trueConstraint =
        new NumberConstraint("green", NumberOperator.IN_INTERVAL, -1, 1);
    NumberConstraint falseConstraint =
        new NumberConstraint("green", NumberOperator.IN_INTERVAL, 2, 3);

    // check state with true constraint
    trans.setGuardDataContainer(tgdc);
    trans.addGuard(trueConstraint);
    trans.checkState();
    assertTrue("An enabled transition is reported to be disabled", trans.isEnabled());

    // check state with additional false constraint
    trans.addGuard(falseConstraint);
    trans.checkState();
    assertFalse("An disabled transition is reported to be enabled", trans.isEnabled());
  }
  /*
   * Test method for {@link de.uni.freiburg.iig.telematik.sepia.petrinet.ifnet.RegularIFNetTransition#setGuardDataContainer(de.uni.freiburg.iig.telematik.sepia.petrinet.ifnet.GuardDataContainer)}. Try to set an valid instance of TestGuradDataContainer as a GuardDataContainer. Add Gurds additionally to check whether the gurads and the container fit.
   */
  @Test
  public void testSetGuardDataContainerGuardFit() throws ParameterException {

    // create the simple standard SNet
    IFNet sNet = null;
    try {
      sNet = IFNetTestUtil.createSimpleIFNet();
    } catch (ParameterException e) {
      fail("Cannot create SNet");
    }

    RegularIFNetTransition trans = (RegularIFNetTransition) sNet.getTransition("t0");

    // Create an instance of TestGuardDataContainer (must be added before guard)
    TestGuardDataContainer tgdc = new TestGuardDataContainer(sNet.getTokenColors());
    try {
      trans.setGuardDataContainer(tgdc);
    } catch (ParameterException e) {
      fail("Exception while setting a vaild GuardDataContainer");
    }

    // add guards
    NumberConstraint guard = null;
    try {
      guard = new NumberConstraint("green", NumberOperator.NOT_IN_INTERVAL, -1, 1);
    } catch (ParameterException e) {
      fail("Cannot create NumberConstraint");
    }

    try {
      trans.addGuard(guard);
    } catch (ParameterException e) {
      fail("Cannot add a valid guard!");
    }

    // Create an instance of TestGuardDataContainer
    // check whether the data container is compatible with the guard
    TestGuardDataContainer tgdc2 = new TestGuardDataContainer(sNet.getTokenColors(), String.class);
    try {
      trans.setGuardDataContainer(tgdc2);
      fail("Invaild GuardDataContainer was set successfully!");
    } catch (ParameterException e) {
    }
  }
  /*
   * Test method for {@link de.uni.freiburg.iig.telematik.sepia.petrinet.ifnet.RegularIFNetTransition#setGuardDataContainer(de.uni.freiburg.iig.telematik.sepia.petrinet.ifnet.GuardDataContainer)}. Try to set an valid instance of TestGuradDataContainer as a GuardDataContainer.
   */
  @Test
  public void testSetGuardDataContainer() throws ParameterException {

    // create the simple standard SNet
    IFNet sNet = IFNetTestUtil.createSimpleIFNet();
    RegularIFNetTransition trans = (RegularIFNetTransition) sNet.getTransition("t0");

    // Create an instance of TestGuardDataContainer
    TestGuardDataContainer tgdc = new TestGuardDataContainer(sNet.getTokenColors());
    trans.setGuardDataContainer(tgdc);

    // Test is ok if no exception gets thrown!
  }
  /*
   * Test method for {@link de.uni.freiburg.iig.telematik.sepia.petrinet.ifnet.RegularIFNetTransition#setGuardDataContainer(de.uni.freiburg.iig.telematik.sepia.petrinet.ifnet.GuardDataContainer)}. Try to set an invalid instance of TestGuradDataContainer as a GuardDataContainer.
   */
  @Test(expected = ParameterException.class)
  public void testSetGuardDataContainerInvalid() throws ParameterException {

    // create the simple standard SNet
    IFNet sNet = IFNetTestUtil.createSimpleIFNet();
    RegularIFNetTransition trans = (RegularIFNetTransition) sNet.getTransition("t0");

    // Create an invald instance of TestGuardDataContainer
    Set<String> colors = sNet.getTokenColors();
    colors.remove("green");
    TestGuardDataContainer tgdc = new TestGuardDataContainer(colors);
    trans.setGuardDataContainer(tgdc);

    // Test is ok if a parameter exception is thrown
  }
  /*
   * Test method for {@link de.uni.freiburg.iig.telematik.sepia.petrinet.ifnet.RegularIFNetTransition#removeGuard(de.invation.code.toval.constraint.AbstractConstraint)}.
   */
  @Test
  public void testRemoveGuard() throws ParameterException {
    IFNet sNet = IFNetTestUtil.createSimpleIFNet();
    RegularIFNetTransition trans = (RegularIFNetTransition) sNet.getTransition("tIn");

    // Get the gurads and check there are no guards initially
    Set<AbstractConstraint<?>> guards = trans.getGuards();
    assertTrue(guards.isEmpty());

    // add a guard and make sure it is really there
    trans.setGuardDataContainer(new TestGuardDataContainer(sNet.getTokenColors()));
    NumberConstraint nc = new NumberConstraint("green", NumberOperator.LARGER, -3);
    trans.addGuard(nc);
    assertFalse(guards.isEmpty());

    // remove it again
    trans.removeGuard(nc);
    assertTrue(guards.isEmpty());
  }