package com.leanwo.activiti.service.base.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.inject.Inject;
import javax.inject.Named;

import org.activiti.engine.ManagementService;
import org.activiti.engine.impl.cmd.AbstractCustomSqlExecution;
import org.activiti.engine.repository.ProcessDefinition;

import com.leanwo.activiti.dto.BaseResponse;
import com.leanwo.activiti.exception.ServerException;
import com.leanwo.activiti.service.base.DeploymentVariable;
import com.leanwo.activiti.service.base.DeploymentVariableMapper;
import com.leanwo.activiti.service.base.DeploymentVariableService;

@Named
public class DeploymentVariableServiceImpl implements DeploymentVariableService{

	@Inject 
	private ManagementService managementService ;
	
	
	private AbstractCustomSqlExecution<DeploymentVariableMapper, DeploymentVariable> getUniqueCommand(String deploymentId, String name) {
		AbstractCustomSqlExecution<DeploymentVariableMapper, DeploymentVariable> abstractCustomSqlExecution = new AbstractCustomSqlExecution<DeploymentVariableMapper, DeploymentVariable>(DeploymentVariableMapper.class) {
			@Override
			public DeploymentVariable execute(DeploymentVariableMapper mapper) {
				return mapper.uniqueByDeploymentIdName(deploymentId, name);
			}
		};
		return abstractCustomSqlExecution;
	}
	

	private AbstractCustomSqlExecution<DeploymentVariableMapper, Integer> getInsertCommand(String id, String deploymentId, String name, String value, int rev) {
		AbstractCustomSqlExecution<DeploymentVariableMapper, Integer> abstractCustomSqlExecution = new AbstractCustomSqlExecution<DeploymentVariableMapper, Integer>(DeploymentVariableMapper.class) {
			@Override
			public Integer execute(DeploymentVariableMapper mapper) {
				return mapper.insert(id, deploymentId, name, value, rev);
			}
		};
		return abstractCustomSqlExecution;
	}

	private AbstractCustomSqlExecution<DeploymentVariableMapper, Integer> getUpdateCommand(String id, String deploymentId, String name, String value, int rev) {
		AbstractCustomSqlExecution<DeploymentVariableMapper, Integer> abstractCustomSqlExecution = new AbstractCustomSqlExecution<DeploymentVariableMapper, Integer>(DeploymentVariableMapper.class) {
			@Override
			public Integer execute(DeploymentVariableMapper mapper) {
				return mapper.update(id, deploymentId, name, value, rev);
			}
		};
		return abstractCustomSqlExecution;
	}
	
	@Override
	public void save(String deploymentId, String name, String value) {
		AbstractCustomSqlExecution<DeploymentVariableMapper, DeploymentVariable> uniqueCommand = getUniqueCommand(deploymentId, name);
		DeploymentVariable deploymentVariable = managementService.executeCustomSql(uniqueCommand);
		if(deploymentVariable == null) {
			String id = UUID.randomUUID().toString();
			AbstractCustomSqlExecution<DeploymentVariableMapper, Integer> insertCommand = getInsertCommand(id, deploymentId, name, value, 1);			
			int count = managementService.executeCustomSql(insertCommand);
			if(count != 1) {
				String message = String.format("部署变量保存失败。(deploymentId = %s, name = %s, value = %s)", deploymentId, name, value);
				throw new ServerException(message);
			}
		}else {
			AbstractCustomSqlExecution<DeploymentVariableMapper, Integer> updateCommand = getUpdateCommand(deploymentVariable.getId(), deploymentId, name, value, deploymentVariable.getRev());	
			int count = managementService.executeCustomSql(updateCommand);
			if(count != 1) {
				String message = String.format("部署变量保存失败。(deploymentId = %s, name = %s, value = %s)", deploymentId, name, value);
				throw new ServerException(message);
			}
		}
	}
	
	@Override
	public DeploymentVariable uniqueByDeploymentIdName(String deploymentId, String name) {
		AbstractCustomSqlExecution<DeploymentVariableMapper, DeploymentVariable> uniqueCommand = getUniqueCommand(deploymentId, name);
		DeploymentVariable deploymentVariable = managementService.executeCustomSql(uniqueCommand);
		return deploymentVariable;
	}
	

	@Override
	public BaseResponse addDeploymentVariables(String deploymentId, Map<String, String> deploymentExtraDatas) {
		BaseResponse baseResponse = new BaseResponse();
		
		for(String name : deploymentExtraDatas.keySet()) {
			String value = deploymentExtraDatas.get(name);
			save(deploymentId, name, value);
		}
		
		baseResponse.setErrorCode(0);
		return baseResponse;
	}


	@Override
	public Map<String, String> listDeploymentVariables(String deploymentId, List<String> variableNames) {
		if(variableNames == null) {
			return null;
		}
		
		Map<String, String> results = new HashMap<String, String>();
		for(String name : variableNames) {
			DeploymentVariable deploymentVariable = uniqueByDeploymentIdName(deploymentId, name);
			if(deploymentVariable == null) {
				results.put(name, null);
			}else {
				results.put(name, deploymentVariable.getValue());
			}
		}
		
		return results;
	}
}
