import java.io.File;
import java.io.FileInputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.transaction.TransactionManager;

import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.SystemEventListenerFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.marshalling.impl.MarshallingConfigurationImpl;
import org.drools.marshalling.impl.ProtobufMarshaller;
import org.drools.persistence.jpa.JPAKnowledgeService;
import org.drools.runtime.Environment;
import org.drools.runtime.EnvironmentName;
import org.drools.runtime.StatefulKnowledgeSession;
import org.jbpm.process.workitem.wsht.LocalHTWorkItemHandler;
import org.jbpm.task.Group;
import org.jbpm.task.User;
import org.jbpm.task.service.TaskService;
import org.jbpm.task.service.local.LocalTaskService;
import org.jbpm.task.utils.OnErrorAction;

import bitronix.tm.TransactionManagerServices;
import bitronix.tm.resource.jdbc.PoolingDataSource;


public class BelmezBugTestCase {

	public static void main(String args[]){
		try {
			
			PoolingDataSource ds = new PoolingDataSource();
			ds.setUniqueName( "jdbc/BitronixJTADataSource" );
			ds.setClassName( "org.h2.jdbcx.JdbcDataSource" );
			ds.setMaxPoolSize( 3 );
			ds.setAllowLocalTransactions( true );
			ds.getDriverProperties().put( "user", "sa" );
			ds.getDriverProperties().put( "password", "sasa" );
			ds.getDriverProperties().put( "URL", "jdbc:h2:mem:mydb" );
			ds.init();
			System.out.println("Registered H2 mem datasource inside Bitronix's JNDI");
			
			Environment env = KnowledgeBaseFactory.newEnvironment();
			EntityManagerFactory emf = Persistence.createEntityManagerFactory("org.jbpm.persistence.jpa");
			TransactionManager tm = TransactionManagerServices.getTransactionManager();
			System.out.println("Created JPA EntityManager");
			
			env.set( EnvironmentName.ENTITY_MANAGER_FACTORY, emf );
			env.set( EnvironmentName.TRANSACTION_MANAGER, TransactionManagerServices.getTransactionManager() );
			TaskService taskService = new org.jbpm.task.service.TaskService(emf, SystemEventListenerFactory.getSystemEventListener());
			Map<String, User> users = new HashMap<String, User>();
			users.put("Administrator", new User("Administrator"));
			Map<String, Group> groups = new HashMap<String, Group>();
			taskService.addUsersAndGroups(users, groups);
			org.jbpm.task.TaskService humanTaskClient = new LocalTaskService(taskService);;
			
			System.out.println("Task service created");
			
			KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
			kbuilder.add(ResourceFactory.newInputStreamResource(new FileInputStream(new File("testcase.bpmn"))),ResourceType.BPMN2);
			if (kbuilder.getErrors()!=null){
				for(KnowledgeBuilderError error: kbuilder.getErrors()){
					System.err.println(error.toString());
				}
			}
			System.out.println("BPMN process knowledge acquired");
			
			KnowledgeBase kbase = kbuilder.newKnowledgeBase();
			StatefulKnowledgeSession sesion = JPAKnowledgeService.newStatefulKnowledgeSession( kbase, null, env );
			System.out.println("Created knowledge session");
			
			LocalHTWorkItemHandler localHTWorkItemHandler = new LocalHTWorkItemHandler(humanTaskClient, sesion, OnErrorAction.RETHROW);
			localHTWorkItemHandler.connect();
			sesion.getWorkItemManager().registerWorkItemHandler("Human Task", localHTWorkItemHandler);
			System.out.println("Attached human task work item handler");
			
			for(int i=0;i<10;i++){
				tm.begin();
				System.out.println("Creating process instance: "+ i);
				sesion.startProcess("PROCESS_1");
				if (i%2 == 0) {tm.commit();} else {tm.rollback();}
			}
			
			Connection c = ds.getConnection();
			Statement st = c.createStatement();
			ResultSet rs = st.executeQuery("select rulesbytearray from sessioninfo");
			rs.next();
			Blob b = rs.getBlob("rulesbytearray");
			System.err.println(b);
			
			KnowledgeBuilder builder = KnowledgeBuilderFactory.newKnowledgeBuilder();
			ProtobufMarshaller marshaller = new ProtobufMarshaller(builder.newKnowledgeBase(),new MarshallingConfigurationImpl());
			StatefulKnowledgeSession session = marshaller.unmarshall(b.getBinaryStream());
			
			System.err.println(session);
		} catch (Exception e){
			e.printStackTrace();
		}
	}
	
}
