/*
 * Copyright © 2013-2019 camunda services GmbH and various authors (info@camunda.com)
 *
 * 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.engine.test.api.authorization;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.HashSet;
import java.util.Set;

import org.camunda.bpm.engine.authorization.BatchPermissions;
import org.camunda.bpm.engine.authorization.Permission;
import org.camunda.bpm.engine.authorization.Permissions;
import org.camunda.bpm.engine.authorization.ProcessDefinitionPermissions;
import org.camunda.bpm.engine.authorization.ProcessInstancePermissions;
import org.camunda.bpm.engine.authorization.Resource;
import org.camunda.bpm.engine.authorization.Resources;
import org.junit.Test;

public class PermissionsTest {

  @Test
  public void testNewPermissionsIntegrityToOld() {
    for (Permissions permission : Permissions.values()) {
      String permissionName = permission.getName();
      Permission resolvedPermission = null;
      for (Resource resource : permission.getTypes()) {
        int resourceType = resource.resourceType();
        if (resourceType == Resources.BATCH.resourceType()) {
          resolvedPermission = BatchPermissions.forName(permissionName);
        } else if (resourceType == Resources.PROCESS_DEFINITION.resourceType()) {
          resolvedPermission = ProcessDefinitionPermissions.forName(permissionName);
        } else if (resourceType == Resources.PROCESS_INSTANCE.resourceType()) {
          resolvedPermission = ProcessInstancePermissions.forName(permissionName);
        } else {
          break;
        }
        assertThat(resolvedPermission).isNotNull();
        assertThat(resolvedPermission.getValue()).isEqualTo(permission.getValue());
      }
    }
  }

  @Test
  public void testPermissionsValues() {
    verifyValueAreUniqueAndEven(Permissions.values());
  }

  @Test
  public void testBatchPermissionsValues() {
    verifyValueAreUniqueAndEven(BatchPermissions.values());
  }

  @Test
  public void testProcessInstancePermissionsValues() {
    verifyValueAreUniqueAndEven(ProcessInstancePermissions.values());
  }

  @Test
  public void testProcessDefinitionPermissionsValues() {
    verifyValueAreUniqueAndEven(ProcessDefinitionPermissions.values());
  }

  private void verifyValueAreUniqueAndEven(Permission[] permissions) {
    Set<Integer> values = new HashSet<>();
    for (Permission permission : permissions) {
      int value = permission.getValue();
      // value is unique
      assertThat(values.add(value))
          .overridingErrorMessage("The value '%s' of '%s' permission is not unique. Abother permission already has this value.", value, permission)
          .isTrue();
      if (value != Integer.MAX_VALUE && value != 0) {
        // value is power of 2
        assertThat(isPowerOfTwo(value))
          .overridingErrorMessage("The value '%s' of '%s' permission is invalid. The values must be power of 2.", value, permission)
          .isTrue();
      }
    }
  }

  private boolean isPowerOfTwo(int value) {
    if (value <= 0) {
      return false;
    }
    return (value & (value - 1)) == 0;
  }
}

@@ -1504,53 +1504,8 @@
 );%0D%0A
-      Permission resolvedPermission = null;%0D%0A
     
@@ -1553,24 +1553,71 @@
 Types()) %7B%0D%0A
+        Permission resolvedPermission = null;%0D%0A
         int 
@@ -2160,13 +2160,16 @@
     
-break
+continue
 ;%0D%0A 
@@ -2396,32 +2396,33 @@
 %0A    verifyValue
+s
 AreUniqueAndEven
@@ -2409,36 +2409,42 @@
 luesAreUniqueAnd
-Even
+PowerOfTwo
 (Permissions.val
@@ -2521,32 +2521,33 @@
 %0A    verifyValue
+s
 AreUniqueAndEven
@@ -2542,20 +2542,26 @@
 niqueAnd
-Even
+PowerOfTwo
 (BatchPe
@@ -2661,32 +2661,33 @@
 %0A    verifyValue
+s
 AreUniqueAndEven
@@ -2674,36 +2674,42 @@
 luesAreUniqueAnd
-Even
+PowerOfTwo
 (ProcessInstance
@@ -2813,32 +2813,33 @@
 %0A    verifyValue
+s
 AreUniqueAndEven
@@ -2834,20 +2834,26 @@
 niqueAnd
-Even
+PowerOfTwo
 (Process
@@ -2919,16 +2919,17 @@
 ifyValue
+s
 AreUniqu
@@ -2936,12 +2936,18 @@
 eAnd
-Even
+PowerOfTwo
 (Per
@@ -3255,17 +3255,17 @@
 nique. A
-b
+n
 other pe
@@ -3697,33 +3697,8 @@
  %7B%0D%0A
-    if (value %3C= 0) %7B%0D%0A  
     
@@ -3708,33 +3708,20 @@
 urn 
-false;%0D%0A    %7D%0D%0A    return
+value %3E 0 &&
  (va

fix permissions value check to include all resources