/*
 * Copyright Camunda Services GmbH and/or licensed to Camunda Services GmbH
 * under one or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership. Camunda licenses this file to you under the Apache License,
 * Version 2.0; 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.impl.db;

import java.util.List;

import org.camunda.bpm.cockpit.db.CommandExecutor;
import org.camunda.bpm.cockpit.db.QueryParameters;
import org.camunda.bpm.cockpit.db.QueryService;
import org.camunda.bpm.engine.ProcessEngineException;
import org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.camunda.bpm.engine.impl.db.ListQueryParameterObject;
import org.camunda.bpm.engine.impl.interceptor.Command;
import org.camunda.bpm.engine.impl.interceptor.CommandContext;
import org.camunda.bpm.engine.impl.util.QueryMaxResultsLimitUtil;

public class QueryServiceImpl implements QueryService {

  private CommandExecutor commandExecutor;

  public QueryServiceImpl(CommandExecutor commandExecutor) {
    this.commandExecutor = commandExecutor;
  }

  public <T> List<T> executeQuery(final String statement, final QueryParameters<T> parameter) {
    List<T> queryResult = commandExecutor.executeCommand(new Command<List<T>>() {

      @SuppressWarnings("unchecked")
      public List<T> execute(CommandContext commandContext) {
        commandContext.getAuthorizationManager()
          .enableQueryAuthCheck(parameter.getAuthCheck());

        if (parameter.isMaxResultsLimitEnabled()) {
          QueryMaxResultsLimitUtil.checkMaxResultsLimit(parameter.getMaxResults(),
            getProcessEngineConfiguration(commandContext));
        }

        return (List<T>) commandContext.getDbSqlSession().selectList(statement, parameter);
      }

    });
    return queryResult;
  }

  public <T> T executeQuery(final String statement, final Object parameter, final Class<T> clazz) {
      T queryResult = commandExecutor.executeCommand(new Command<T>() {

      @SuppressWarnings("unchecked")
      public T execute(CommandContext commandContext) {
        return (T) commandContext.getDbSqlSession().selectOne(statement, parameter);
      }

    });
    return queryResult;
  }

  public Long executeQueryRowCount(final String statement, final ListQueryParameterObject parameter) {
    Long queryResult = commandExecutor.executeCommand(new Command<Long>() {

      public Long execute(CommandContext commandContext) {
        commandContext.getAuthorizationManager()
          .enableQueryAuthCheck(parameter.getAuthCheck());
        return (Long) commandContext.getDbSqlSession().selectOne(statement, parameter);
      }

    });
    return queryResult;
  }

  protected ProcessEngineConfigurationImpl getProcessEngineConfiguration(
    CommandContext commandContext) {
    QuerySessionFactory querySessionFactory =
      (QuerySessionFactory) commandContext.getProcessEngineConfiguration();

    ProcessEngineConfigurationImpl processEngineConfiguration = null;
    if (querySessionFactory != null) {
      processEngineConfiguration = querySessionFactory.getWrappedConfiguration();
    }

    if (processEngineConfiguration == null) {
      throw new ProcessEngineException("Process Engine Configuration missing!");
    }

    return processEngineConfiguration;
  }

}

@@ -1184,32 +1184,26 @@
 .db.
-ListQueryParameterObject
+AuthorizationCheck
 ;%0Aim
@@ -1235,35 +1235,43 @@
 ne.impl.
-interceptor.Command
+db.ListQueryParameterObject
 ;%0Aimport
@@ -1709,29 +1709,14 @@
     
-List%3CT%3E queryResult =
+return
  com
@@ -1747,115 +1747,110 @@
 and(
-new C
+c
 ommand
-%3CList%3CT%3E%3E()
+Context -%3E
  %7B%0A
-%0A
       
-@SuppressWarnings(%22unchecked%22)%0A      public List%3CT%3E execute(CommandContext 
+ProcessEngineConfigurationImpl engineConfig = getProcessEngineConfiguration(
 comm
@@ -1864,122 +1864,79 @@
 ext)
- %7B%0A 
+;%0A%0A
       
- 
 co
-mmandContext.getAuthorizationManager()%0A          .enableQueryAuthCheck(parameter.getAuthCheck()
+nfigureAuthCheck(parameter, engineConfig, commandContext
 );%0A%0A
-  
     
@@ -1977,26 +1977,24 @@
 nabled()) %7B%0A
-  
         Quer
@@ -2065,71 +2065,24 @@
 s(),
-%0A            getProcessEngineConfiguration(commandContext)
+ engineConfig
 );%0A
-  
     
@@ -2086,18 +2086,16 @@
      %7D%0A%0A
-  
       re
@@ -2137,24 +2137,33 @@
 SqlSession()
+%0A        
 .selectList(
@@ -2193,43 +2193,10 @@
     
-  %7D%0A%0A    %7D);%0A    return queryResult
+%7D)
 ;%0A  
@@ -2306,25 +2306,14 @@
     
-  T queryResult =
+return
  com
@@ -2344,135 +2344,25 @@
 and(
-new Command%3CT%3E() %7B%0A%0A      @SuppressWarnings(%22unchecked%22)%0A      public T execute(CommandContext commandContext) %7B%0A        return
+commandContext -%3E
  (T)
@@ -2386,32 +2386,39 @@
 etDbSqlSession()
+%0A      
 .selectOne(state
@@ -2437,49 +2437,9 @@
 ter)
-;%0A      %7D%0A%0A    %7D);%0A    return queryResult
+)
 ;%0A  
@@ -2552,26 +2552,14 @@
     
-Long queryResult =
+return
  com
@@ -2590,200 +2590,196 @@
 and(
-new C
+c
 ommand
-%3CLong%3E()
+Context -%3E
  %7B%0A
-%0A
       
-public Long execute(CommandContext commandContext) %7B%0A        commandContext.getAuthorizationManager()%0A          .enableQueryAuthCheck(parameter.getAuthCheck());%0A  
+ProcessEngineConfigurationImpl engineConfig = getProcessEngineConfiguration(commandContext);%0A%0A      configureAuthCheck(parameter, engineConfig, commandContext);%0A%0A
     
@@ -2868,43 +2868,10 @@
     
-  %7D%0A%0A    %7D);%0A    return queryResult
+%7D)
 ;%0A  
@@ -3483,10 +3483,592 @@
 n;%0A  %7D%0A%0A
+  protected  %3CT%3E void configureAuthCheck(ListQueryParameterObject parameter,%0A                                         ProcessEngineConfigurationImpl engineConfig,%0A                                         CommandContext commandContext) %7B%0A    AuthorizationCheck authCheck = parameter.getAuthCheck();%0A%0A    commandContext.getAuthorizationManager()%0A      .enableQueryAuthCheck(authCheck);%0A%0A    boolean isEnableHistoricInstancePermissions = engineConfig.isEnableHistoricInstancePermissions();%0A    authCheck.setHistoricInstancePermissionsEnabled(isEnableHistoricInstancePermissions);%0A  %7D%0A%0A
 %7D%0A

add historic instance permission check