package it.reply.workflowmanager.spring.orchestrator.config;

import it.reply.workflowmanager.orchestrator.config.ConfigProducer;
import it.reply.workflowmanager.spring.orchestrator.annotations.PerProcessInstance;
import it.reply.workflowmanager.spring.orchestrator.annotations.PerRequest;
import it.reply.workflowmanager.spring.orchestrator.annotations.Singleton;
import it.reply.workflowmanager.spring.orchestrator.annotations.WorkflowPersistenceUnit;
import it.reply.workflowmanager.utils.Constants;
import org.jbpm.runtime.manager.impl.SimpleRuntimeEnvironment;
import org.kie.api.executor.ExecutorService;
import org.kie.api.runtime.manager.RuntimeEnvironment;
import org.kie.api.runtime.manager.RuntimeManager;
import org.kie.spring.factorybeans.RuntimeEnvironmentFactoryBean;
import org.kie.spring.factorybeans.RuntimeManagerFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;

import java.util.HashMap;

import javax.persistence.EntityManagerFactory;

@Configuration
public class WorkflowRuntimeConfig {

  @Autowired
  private ConfigProducer configProducer;

  @Autowired
  private AutowireableRegisterableItemsFactory customRegisterableItemsFactory;

  @Autowired
  @WorkflowPersistenceUnit
  private EntityManagerFactory entityManagerFactory;

  @Autowired
  private PlatformTransactionManager transactionManager;

  @Autowired
  private ExecutorService executorService;

  @Bean(destroyMethod = "close")
  public RuntimeEnvironment runtimeEnvironment() throws Exception {
    RuntimeEnvironmentFactoryBean refb = new RuntimeEnvironmentFactoryBean();
    refb.setType(RuntimeEnvironmentFactoryBean.TYPE_DEFAULT);
    refb.setEntityManagerFactory(entityManagerFactory);

    // refb.setUserGroupCallback(userGroupCallback);
    refb.setRegisterableItemsFactory(customRegisterableItemsFactory);

    refb.setPessimisticLocking(true);
    refb.setTransactionManager(transactionManager);
    refb.setEnvironmentEntries(new HashMap<String, Object>());
    refb.getEnvironmentEntries().put(Constants.EXECUTOR_SERVICE, executorService);
    SimpleRuntimeEnvironment env = (SimpleRuntimeEnvironment) refb.getObject();
    env.setUsePersistence(true);
    for (org.kie.api.io.Resource resource : configProducer.getJbpmResources()) {
      env.addAsset(resource, resource.getResourceType());
    }
    return env;
  }

//  @Bean(destroyMethod = "close")
//  @Singleton
//  public RuntimeManager singletonRuntimeManager() throws Exception {
//    RuntimeManagerFactoryBean rmfb = new RuntimeManagerFactoryBean();
//    rmfb.setIdentifier("default-singleton");
//    rmfb.setRuntimeEnvironment(runtimeEnvironment());
//    rmfb.setType("SINGLETON");
//    RuntimeManager rm = (RuntimeManager) rmfb.getObject();
//    return rm;
//  }

  @Bean(destroyMethod = "close")
  @PerProcessInstance
  public RuntimeManager perProcessInstanceRuntimeManager() throws Exception {
    RuntimeManagerFactoryBean rmfb = new RuntimeManagerFactoryBean();
    rmfb.setIdentifier("default-per-process");
    rmfb.setRuntimeEnvironment(runtimeEnvironment());
    rmfb.setType("PER_PROCESS_INSTANCE");
    RuntimeManager rm = (RuntimeManager) rmfb.getObject();
    return rm;
  }

//  @Bean(destroyMethod = "close")
//  @PerRequest
//  public RuntimeManager perRequesteRuntimeManager() throws Exception {
//    RuntimeManagerFactoryBean rmfb = new RuntimeManagerFactoryBean();
//    rmfb.setIdentifier("default-per-request");
//    rmfb.setRuntimeEnvironment(runtimeEnvironment());
//    rmfb.setType("PER_REQUEST");
//    RuntimeManager rm = (RuntimeManager) rmfb.getObject();
//    return rm;
//  }
}

@@ -2592,16 +2592,27 @@
 eManager
+FactoryBean
  singlet
@@ -2619,32 +2619,43 @@
 onRuntimeManager
+FactoryBean
 () throws Except
@@ -2866,32 +2866,115 @@
 GLETON%22);%0A//    
+return rmfb;%0A//  %7D%0A//%0A//  @Bean(destroyMethod = %22close%22)%0A//  @Singleton%0A//  public 
 RuntimeManager r
@@ -2964,38 +2964,41 @@
  RuntimeManager 
-rm = (
+singleton
 RuntimeManager) 
@@ -2999,43 +2999,108 @@
 ager
+(
 ) 
-rmfb.getObject();%0A//    return rm
+throws Exception %7B%0A//    return (RuntimeManager) singletonRuntimeManagerFactoryBean().getObject()
 ;%0A//
@@ -3178,24 +3178,35 @@
 ntimeManager
+FactoryBean
  perProcessI
@@ -3218,32 +3218,43 @@
 ceRuntimeManager
+FactoryBean
 () throws Except
@@ -3480,76 +3480,244 @@
     
-RuntimeManager rm = (RuntimeManager) rmfb.getObject();%0A    return rm
+return rmfb;%0A  %7D%0A%0A  @Bean(destroyMethod = %22close%22)%0A  @PerProcessInstance%0A  public RuntimeManager perProcessInstanceRuntimeManager() throws Exception %7B%0A    return (RuntimeManager) perProcessInstanceRuntimeManagerFactoryBean().getObject()
 ;%0A  
@@ -3791,24 +3791,35 @@
 ntimeManager
+FactoryBean
  perRequeste
@@ -3824,32 +3824,43 @@
 teRuntimeManager
+FactoryBean
 () throws Except
@@ -4079,24 +4079,108 @@
 ST%22);%0A//    
+return rmfb;%0A//  %7D%0A//%0A//  @Bean(destroyMethod = %22close%22)%0A//  @PerRequest%0A//  public 
 RuntimeManag
@@ -4186,14 +4186,19 @@
 ger 
-rm = (
+perRequeste
 Runt
@@ -4211,43 +4211,110 @@
 ager
+(
 ) 
-rmfb.getObject();%0A//    return rm
+throws Exception %7B%0A//    return (RuntimeManager) perRequesteRuntimeManagerFactoryBean().getObject()
 ;%0A//

Improve RuntimeManager beans generation