package org.activiti.standalone.cfg;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import org.activiti.engine.impl.cmd.AbstractCustomSqlExecution;
import org.activiti.engine.impl.cmd.CustomSqlExecution;
import org.activiti.engine.impl.test.ResourceActivitiTestCase;
import org.activiti.engine.task.Task;

/**
 * @author jbarrez
 */
public class CustomMybatisMapperTest extends ResourceActivitiTestCase {
	
	public CustomMybatisMapperTest() {
		super("org/activiti/standalone/cfg/custom-mybatis-mappers-activiti.cfg.xml");
	}
	
	public void testSelectTaskColumns() {
		
		// Create test data
		for (int i=0; i<5; i++) {
			Task task = taskService.newTask();
			task.setName(i + "");
			taskService.saveTask(task);
		}
		
		// Fetch the columns we're interested in
		CustomSqlExecution<MyTestMapper, List<Map<String, Object>>> customSqlExecution = 
				new AbstractCustomSqlExecution<MyTestMapper, List<Map<String, Object>>>(MyTestMapper.class) {
			
			public List<Map<String, Object>> execute(MyTestMapper customMapper) {
				return customMapper.selectTasks();
			}
		
		};
		
		// Verify
		List<Map<String, Object>> tasks = managementService.executeCustomSql(customSqlExecution);
		assertEquals(5, tasks.size());
		for (int i=0; i<5; i++) {
			Map<String, Object> task = tasks.get(i);
			assertNotNull(task.get("ID"));
			assertNotNull(task.get("NAME"));
			assertNotNull(task.get("CREATETIME"));
		}
		
		// Cleanup
		for (Task task : taskService.createTaskQuery().list()) {
			taskService.deleteTask(task.getId());
			historyService.deleteHistoricTaskInstance(task.getId());
		}
		
	}
	
	public void testFetchTaskWithSpecificVariable() {
		
		// Create test data
		for (int i=0; i<5; i++) {
			Task task = taskService.newTask();
			task.setName(i + "");
			taskService.saveTask(task);
			
			taskService.setVariable(task.getId(), "myVar", Long.valueOf(task.getId()) * 2);
			taskService.setVariable(task.getId(), "myVar2", "SomeOtherValue");
		}
		
		// Fetch data with custom query
		CustomSqlExecution<MyTestMapper, List<Map<String, Object>>> customSqlExecution = 
				new AbstractCustomSqlExecution<MyTestMapper, List<Map<String, Object>>>(MyTestMapper.class) {
			
			public List<Map<String, Object>> execute(MyTestMapper customMapper) {
				return customMapper.selectTaskWithSpecificVariable("myVar");
			}
		
		};
		
		// Verify
		List<Map<String, Object>> results = managementService.executeCustomSql(customSqlExecution);
		assertEquals(5, results.size());
		for (int i=0; i<5; i++) {
			Map<String, Object> result = results.get(i);
			Long id = Long.valueOf((String) result.get("TASKID"));
			Long variableValue = null;
			if (result.get("VARIABLEVALUE") instanceof BigDecimal) { // in oracle it's BigDecimal
			  variableValue = ((BigDecimal)result.get("VARIABLEVALUE")).longValue();
			} else {
			  variableValue = (Long) result.get("VARIABLEVALUE");
			}
			assertEquals(id * 2, variableValue.longValue());
		}
		
		// Cleanup
		for (Task task : taskService.createTaskQuery().list()) {
			taskService.deleteTask(task.getId());
			historyService.deleteHistoricTaskInstance(task.getId());
		}
		
	}
	
}

@@ -1330,21 +1330,34 @@
 ull(
-task.get(%22ID%22
+getResultObject(%22ID%22, task
 ));%0A
@@ -1377,23 +1377,30 @@
 ull(
-task.ge
+getResultObjec
 t(%22NAME%22
 ));%0A
@@ -1395,16 +1395,22 @@
 t(%22NAME%22
+, task
 ));%0A%09%09%09a
@@ -1422,23 +1422,30 @@
 NotNull(
-task.ge
+getResultObjec
 t(%22CREAT
@@ -1450,16 +1450,22 @@
 ATETIME%22
+, task
 ));%0A%09%09%7D%0A
@@ -2640,25 +2640,30 @@
 String) 
-r
+getR
 esult
-.ge
+Objec
 t(%22TASKI
@@ -2664,16 +2664,24 @@
 %22TASKID%22
+, result
 ));%0A%09%09%09L
@@ -2713,39 +2713,105 @@
 %0A%09%09%09
-if (result.get(%22VARIABLEVALUE%22)
+Object variableObjectValue = getResultObject(%22VARIABLEVALUE%22, result);%0A%09%09%09if (variableObjectValue
  ins
@@ -2899,35 +2899,27 @@
 mal)
-result.get(%22VARIABLEVALUE%22)
+variableObjectValue
 ).lo
@@ -2973,35 +2973,27 @@
 ng) 
-result.get(%22VARIABLEVALUE%22)
+variableObjectValue
 ;%0A%09%09
@@ -3239,10 +3239,272 @@
 %09%09%0A%09%7D%0A%09%0A
+%09protected Object getResultObject(String key, Map%3CString, Object%3E result) %7B%0A%09%09Object resultObject = result.get(key);%0A%09%09if (resultObject == null) %7B // postgresql requires lower case%0A%09%09%09resultObject = result.get(key.toLowerCase());%0A%09%09%7D%0A%09%09return resultObject;%0A%09%7D%0A%09%0A
 %7D%0A

fix test on postgresql