/* Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.camunda.bpm.cockpit.plugin.base.tenantcheck;

import static org.fest.assertions.Assertions.assertThat;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.camunda.bpm.cockpit.impl.plugin.base.dto.IncidentDto;
import org.camunda.bpm.cockpit.impl.plugin.base.dto.query.IncidentQueryDto;
import org.camunda.bpm.cockpit.impl.plugin.resources.IncidentRestService;
import org.camunda.bpm.cockpit.plugin.test.AbstractCockpitPluginTest;
import org.camunda.bpm.engine.IdentityService;
import org.camunda.bpm.engine.ProcessEngine;
import org.camunda.bpm.engine.ProcessEngineConfiguration;
import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.authorization.Groups;
import org.junit.Before;
import org.junit.Test;

public class IncidentRestServiceTenantCheckTest extends AbstractCockpitPluginTest {

  protected static final String TENANT_ONE = "tenant1";
  protected static final String TENANT_TWO = "tenant2";

  private ProcessEngine processEngine;
  private ProcessEngineConfiguration processEngineConfiguration;
  private RuntimeService runtimeService;
  private IdentityService identityService;

  private IncidentRestService resource;
  private IncidentQueryDto queryParameter;

  private String processInstanceTenantOne;
  private String processInstanceTenantTwo;

  @Before
  public void init() throws Exception {

    processEngine = getProcessEngine();
    processEngineConfiguration = processEngine.getProcessEngineConfiguration();

    runtimeService = processEngine.getRuntimeService();
    identityService = processEngine.getIdentityService();

    resource = new IncidentRestService(processEngine.getName());

    deployForTenant(TENANT_ONE, "processes/failing-process.bpmn");
    deployForTenant(TENANT_TWO, "processes/failing-process.bpmn");

    processInstanceTenantOne = runtimeService.createProcessInstanceByKey("FailingProcess")
        .processDefinitionTenantId(TENANT_ONE).execute().getId();

    processInstanceTenantTwo = runtimeService.createProcessInstanceByKey("FailingProcess")
        .processDefinitionTenantId(TENANT_TWO).execute().getId();

    executeAvailableJobs();

    queryParameter = new IncidentQueryDto();
    queryParameter.setProcessInstanceIdIn(new String[]{processInstanceTenantOne, processInstanceTenantTwo});
  }

  @Test
  public void queryIncidentsByProcessInstanceIdsNoAuthenticatedTenants() {

    identityService.setAuthentication("user", null, null);

    List<IncidentDto> result = resource.queryIncidents(queryParameter, null, null);
    assertThat(result).isEmpty();
  }

  @Test
  public void queryIncidentsByProcessInstanceIdsWithAuthenticatedTenant() {

    identityService.setAuthentication("user", null, Arrays.asList(TENANT_ONE));

    List<IncidentDto> result = resource.queryIncidents(queryParameter, null, null);
    assertThat(result).isNotEmpty();
    assertThat(result).hasSize(1);

    IncidentDto incident = result.get(0);
    assertThat(incident.getProcessInstanceId()).isEqualTo(processInstanceTenantOne);
  }

  @Test
  public void queryIncidentsByProcessInstanceIdsDisabledTenantCheck() {

    processEngineConfiguration.setTenantCheckEnabled(false);
    identityService.setAuthentication("user", null, null);

    List<IncidentDto> result = resource.queryIncidents(queryParameter, null, null);
    assertThat(result).isNotEmpty();
    assertThat(result).hasSize(2);

    IncidentDto incident1 = result.get(0);
    assertThat(incident1.getProcessInstanceId()).isEqualTo(processInstanceTenantOne);

    IncidentDto incident2 = result.get(1);
    assertThat(incident2.getProcessInstanceId()).isEqualTo(processInstanceTenantTwo);
  }

  @Test
  public void queryIncidentsByProcessInstanceIdsWithCamundaAdmin() {

    identityService.setAuthentication("user", Collections.singletonList(Groups.CAMUNDA_ADMIN), null);

    List<IncidentDto> result = resource.queryIncidents(queryParameter, null, null);
    assertThat(result).isNotEmpty();
    assertThat(result).hasSize(2);

    IncidentDto incident1 = result.get(0);
    assertThat(incident1.getProcessInstanceId()).isEqualTo(processInstanceTenantOne);

    IncidentDto incident2 = result.get(1);
    assertThat(incident2.getProcessInstanceId()).isEqualTo(processInstanceTenantTwo);
  }

}

@@ -741,19 +741,67 @@
 va.util.
-Lis
+HashSet;%0Aimport java.util.List;%0Aimport java.util.Se
 t;%0A%0Aimpo
@@ -3963,62 +3963,90 @@
 lt).
-isNotEmpty(
+hasSize(2
 );%0A
+%0A
     
-assertThat(result).hasSize(2
+Set%3CString%3E processInstnaceIds = new HashSet%3CString%3E(
 );%0A
-%0A
     
+for (
 Inci
@@ -4065,41 +4065,52 @@
 dent
-1 =
+Dto :
  result
-.get(0);%0A    assertThat
+) %7B%0A      processInstnaceIds.add
 (inc
@@ -4106,33 +4106,35 @@
 Ids.add(incident
-1
+Dto
 .getProcessInsta
@@ -4145,87 +4145,85 @@
 d())
-.isEqualTo(processInstanceTenantOne);%0A%0A    IncidentDto incident2 = result.get(1
+;%0A    %7D%0A%0A    assertThat(processInstnaceIds).contains(processInstanceTenantOne
 );%0A 
@@ -4232,38 +4232,25 @@
  assertThat(
-incident2.getP
+p
 rocessInstan
@@ -4247,35 +4247,33 @@
 cessInst
-a
 n
+a
 ceId
-()).isEqualTo
+s).contains
 (process
@@ -4470,32 +4470,33 @@
 ADMIN), null);%0A%0A
+%0A
     List%3CInciden
@@ -4590,62 +4590,90 @@
 lt).
-isNotEmpty(
+hasSize(2
 );%0A
+%0A
     
-assertThat(result).hasSize(2
+Set%3CString%3E processInstnaceIds = new HashSet%3CString%3E(
 );%0A
-%0A
     
+for (
 Inci
@@ -4692,41 +4692,52 @@
 dent
-1 =
+Dto :
  result
-.get(0);%0A    assertThat
+) %7B%0A      processInstnaceIds.add
 (inc
@@ -4741,17 +4741,19 @@
 incident
-1
+Dto
 .getProc
@@ -4772,87 +4772,85 @@
 d())
-.isEqualTo(processInstanceTenantOne);%0A%0A    IncidentDto incident2 = result.get(1
+;%0A    %7D%0A%0A    assertThat(processInstnaceIds).contains(processInstanceTenantOne
 );%0A 
@@ -4867,22 +4867,9 @@
 hat(
-incident2.getP
+p
 roce
@@ -4874,35 +4874,33 @@
 cessInst
-a
 n
+a
 ceId
-()).isEqualTo
+s).contains
 (process

make independent of ordering