/* 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.standalone.scripting;

import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import javax.script.ScriptEngine;

import org.camunda.bpm.application.ProcessApplicationInterface;
import org.camunda.bpm.application.impl.EmbeddedProcessApplication;
import org.camunda.bpm.engine.impl.context.Context;
import org.camunda.bpm.engine.impl.interceptor.Command;
import org.camunda.bpm.engine.impl.interceptor.CommandContext;
import org.camunda.bpm.engine.impl.scripting.ExecutableScript;
import org.camunda.bpm.engine.impl.scripting.ScriptFactory;
import org.camunda.bpm.engine.impl.scripting.SourceExecutableScript;
import org.camunda.bpm.engine.impl.scripting.engine.ScriptingEngines;
import org.camunda.bpm.engine.impl.scripting.env.ScriptEnvResolver;
import org.camunda.bpm.engine.impl.scripting.env.ScriptingEnvironment;
import org.camunda.bpm.engine.impl.test.PluggableProcessEngineTestCase;
import org.camunda.bpm.engine.repository.ProcessApplicationDeployment;

/**
 * @author Roman Smirnov
 *
 */
public class EnvScriptCachingTest extends PluggableProcessEngineTestCase {

  protected static final String PROCESS_PATH = "org/camunda/bpm/engine/test/api/oneTaskProcess.bpmn20.xml";
  protected static final String SCRIPT_LANGUAGE = "groovy";
  protected static final String SCRIPT = "println 'hello world'";
  protected static final String ENV_SCRIPT = "println 'hello world from env script'";

  protected ScriptFactory scriptFactory;

  public void setUp() throws Exception {
    super.setUp();
    scriptFactory = processEngineConfiguration.getScriptFactory();
    processEngineConfiguration.getEnvScriptResolvers().add(new ScriptEnvResolver() {
      public String[] resolve(String language) {
        return new String[] { ENV_SCRIPT };
      }
    });
  }

  public void tearDown() {
    processEngineConfiguration.getEnvScriptResolvers().clear();
  }

  public void testEnabledPaEnvScriptCaching() {
    // given
    EmbeddedProcessApplication processApplication = new EmbeddedProcessApplication();

    ProcessApplicationDeployment deployment = repositoryService.createDeployment(processApplication.getReference())
        .addClasspathResource(PROCESS_PATH)
        .deploy();

    // when
    executeScript(processApplication);

    // then
    Map<String, List<ExecutableScript>> environmentScripts = processApplication.getEnvironmentScripts();
    assertNotNull(environmentScripts);

    List<ExecutableScript> groovyEnvScripts = environmentScripts.get(SCRIPT_LANGUAGE);

    assertNotNull(groovyEnvScripts);
    assertFalse(groovyEnvScripts.isEmpty());
    assertEquals(1, groovyEnvScripts.size());

    repositoryService.deleteDeployment(deployment.getId(), true);
  }

  public void testDisabledPaEnvScriptCaching() {
    // given
    processEngineConfiguration.setEnableFetchScriptEngineFromProcessApplication(false);

    EmbeddedProcessApplication processApplication = new EmbeddedProcessApplication();

    ProcessApplicationDeployment deployment = repositoryService.createDeployment(processApplication.getReference())
        .addClasspathResource(PROCESS_PATH)
        .deploy();

    // when
    executeScript(processApplication);

    // then
    Map<String, List<ExecutableScript>> environmentScripts = processApplication.getEnvironmentScripts();
    assertNotNull(environmentScripts);
    assertNull(environmentScripts.get(SCRIPT_LANGUAGE));

    repositoryService.deleteDeployment(deployment.getId(), true);

    processEngineConfiguration.setEnableFetchScriptEngineFromProcessApplication(true);
  }

  protected SourceExecutableScript createScript(String language, String source) {
    return (SourceExecutableScript) scriptFactory.createScriptFromSource(language, source);
  }

  protected void executeScript(final ProcessApplicationInterface processApplication) {
    processEngineConfiguration.getCommandExecutorTxRequired()
      .execute(new Command<Void>() {
        public Void execute(CommandContext commandContext) {
          return Context.executeWithinProcessApplication(new Callable<Void>() {

            public Void call() throws Exception {
              ScriptingEngines scriptingEngines = processEngineConfiguration.getScriptingEngines();
              ScriptEngine scriptEngine = scriptingEngines.getScriptEngineForLanguage(SCRIPT_LANGUAGE);

              SourceExecutableScript script = createScript(SCRIPT_LANGUAGE, SCRIPT);

              ScriptingEnvironment scriptingEnvironment = processEngineConfiguration.getScriptingEnvironment();
              scriptingEnvironment.execute(script, null, null, scriptEngine);

              return null;
            }
          }, processApplication.getReference());
        }
      });
  }

}

@@ -2010,16 +2010,234 @@
 cript'%22;
+%0A  protected static final ScriptEnvResolver RESOLVER;%0A%0A  static %7B%0A    RESOLVER = new ScriptEnvResolver() %7B%0A      public String%5B%5D resolve(String language) %7B%0A        return new String%5B%5D %7B ENV_SCRIPT %7D;%0A      %7D%0A    %7D;%0A  %7D
 %0A%0A  prot
@@ -2462,162 +2462,81 @@
 add(
-new ScriptEnvResolver() %7B%0A      public String%5B%5D resolve(String language) %7B%0A        return new String%5B%5D %7B ENV_SCRIPT %7D;%0A      %7D%0A    %7D);%0A  %7D%0A%0A  public void 
+RESOLVER);%0A  %7D%0A%0A  protected void tearDown() throws Exception %7B%0A    super.
 tear
@@ -2541,18 +2541,17 @@
 arDown()
- %7B
+;
 %0A    pro
@@ -2602,14 +2602,23 @@
 s().
-clear(
+remove(RESOLVER
 );%0A 
@@ -3349,9 +3349,65 @@
 als(
-1
+processEngineConfiguration.getEnvScriptResolvers().size()
 , gr

fix test case in profile check-plugins