package org.camunda.bpm.engine.test.api.runtime;

import static org.junit.Assert.*;

import org.apache.tools.ant.filters.TokenFilter.ContainsString;
import org.camunda.bpm.engine.BadUserRequestException;
import org.camunda.bpm.engine.HistoryService;
import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.history.HistoricIncident;
import org.camunda.bpm.engine.impl.RuntimeServiceImpl;
import org.camunda.bpm.engine.runtime.Incident;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.test.ProcessEngineRule;
import org.camunda.bpm.engine.test.api.runtime.migration.models.ProcessModels;
import org.camunda.bpm.engine.test.util.ProcessEngineTestRule;
import org.camunda.bpm.engine.test.util.ProvidedProcessEngineRule;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.rules.RuleChain;
import static org.hamcrest.CoreMatchers.containsString;

public class CreateAndResolveIncidentTest {

  protected ProcessEngineRule engineRule = new ProvidedProcessEngineRule();
  protected ProcessEngineTestRule testRule = new ProcessEngineTestRule(engineRule);

  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @Rule
  public RuleChain ruleChain = RuleChain.outerRule(engineRule).around(testRule);

  protected RuntimeService runtimeService;
  protected HistoryService historyService;

  @Before
  public void init() {
    runtimeService = engineRule.getRuntimeService();
    historyService = engineRule.getHistoryService();
  }

  @Test
  public void createIncident() {
    // given
    testRule.deploy(ProcessModels.TWO_TASKS_PROCESS);
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Process");

    // when
    Incident incident = runtimeService.createIncident("foo", processInstance.getId(), "userTask1", "bar");

    // then
    HistoricIncident historicIncident = historyService.createHistoricIncidentQuery().executionId(processInstance.getId()).singleResult();
    assertEquals(historicIncident.getId(), incident.getId());
    assertEquals("userTask1", historicIncident.getActivityId());
    assertEquals("foo", historicIncident.getIncidentType());
    assertEquals("bar", historicIncident.getConfiguration());
    assertEquals(processInstance.getId(), historicIncident.getExecutionId());
  }

  @Test
  public void createIncidentWithNullExecution() {

    try {
      runtimeService.createIncident("foo", null, "userTask1", "bar");
      fail("exception expected");
    } catch (BadUserRequestException e) {
      assertThat(e.getMessage(), containsString("Execution id cannot be null"));
    }
  }

  @Test
  public void createIncidentWithNullIncidentType() {
    try {
      runtimeService.createIncident(null, "processInstanceId", "foo", "bar");
      fail("Exception expected");
    } catch (BadUserRequestException e) {
      assertThat(e.getMessage(), containsString("incidentType is null"));
    }
  }

  @Test
  public void createIncidentWithNonExistingExecution() {

    try {
      runtimeService.createIncident("foo", "aaa", "userTask1", "bar");
      fail("exception expected");
    } catch (BadUserRequestException e) {
      assertThat(e.getMessage(), containsString("Cannot find an execution with executionId 'aaa' and activityId 'userTask1'"));
    }
  }

  @Test
  public void resolveIncident() {
    // given
    testRule.deploy(ProcessModels.TWO_TASKS_PROCESS);
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Process");
    Incident incident = runtimeService.createIncident("foo", processInstance.getId(), "userTask1", "bar");

    // when
    runtimeService.resolveIncident(incident.getId());

    // then
    Incident incident2 = runtimeService.createIncidentQuery().executionId(processInstance.getId()).singleResult();
    assertNull(incident2);
  }

  @Test
  public void resolveUnexistingIncident() {
    try {
      runtimeService.resolveIncident("foo");
      fail("Exception expected");
    } catch (BadUserRequestException e) {
      assertThat(e.getMessage(), containsString("Cannot find an incident with id 'foo'"));
    }
  }
}

@@ -1904,24 +1904,16 @@
 hen%0A    
-Historic
 Incident
@@ -1917,34 +1917,27 @@
 ent 
-historicI
+i
 ncident
+2
  = 
-history
+runtime
 Serv
@@ -1946,24 +1946,16 @@
 e.create
-Historic
 Incident
@@ -2032,32 +2032,25 @@
 tEquals(
-historicI
+i
 ncident
+2
 .getId()
@@ -2100,32 +2100,25 @@
 Task1%22, 
-historicI
+i
 ncident
+2
 .getActi
@@ -2152,32 +2152,25 @@
 (%22foo%22, 
-historicI
+i
 ncident
+2
 .getInci
@@ -2206,32 +2206,25 @@
 (%22bar%22, 
-historicI
+i
 ncident
+2
 .getConf
@@ -2283,24 +2283,17 @@
 (), 
-historicI
+i
 ncident
+2
 .get

fix NullPointerException in CreateAndResolveIncidentTest