package com.jeeplus.modules.act.service;

import java.util.ArrayList;
import java.util.List;

import com.jeeplus.common.config.Global;
import com.jeeplus.common.service.BaseService;
import com.jeeplus.common.utils.DateUtils;
import com.jeeplus.modules.sys.entity.Role;
import com.jeeplus.modules.sys.utils.UserUtils;
import com.jeeplus.modules.workactivity.entity.Activity;
import org.activiti.bpmn.BpmnAutoLayout;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.EndEvent;
import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang.StringUtils;
import org.junit.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 */

/**
 * @ClassName: ActivitiTest01
 * @Description: TODO(activiti 工作流程图自动生成)
 * @author liang
 * @date 2016年4月20日 上午8:32:56
 *
 */
@Service
@Transactional(readOnly = true)
public class ActivityXmlService extends BaseService {
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;

    public static void main(String[] args) {
       /* try {
            ActivityService.test01();
        } catch (IOException e) {
            e.printStackTrace();
        }*/
    }

    @Transactional(readOnly = false)
    public void createActivityXml(String PROCESSID,String PROCESSNAME,List<Activity> list) {
        logger.info(".........start...");
        // 1. Build up the model from scratch
        BpmnModel model = new BpmnModel();
        Process process=new Process();
        model.addProcess(process);
        process.setId(PROCESSID);
        process.setName(PROCESSNAME);
        process.addFlowElement(createStartEvent());
        for (int i = 0;i<list.size();i++){
            Activity activity=list.get(i);
            List<String> candidateGroupList=new ArrayList<String>();
            if(activity.getRole().getEnname().contains("dsz") || activity.getRole().getEnname().contains("zjl") ){
                Role role = UserUtils.getSelectRole().get(0);
                String buffer = DateUtils.getByEnnme(role.getEnname()).toString();
                candidateGroupList.add(buffer+"dsz");
                candidateGroupList.add(buffer+"zjl");
            }
            String user = "";
            /*String role = "";
            if (activity.getUser()!=null && StringUtils.isNotBlank(activity.getUser().getId())){
                user = "${user"+(i+1)+"}";
            }
            if (activity.getRole()!=null && StringUtils.isNotBlank(activity.getRole().getEnname())){
                role = "${role"+(i+1)+"}";
            }*/
            process.addFlowElement(createUserTask("task"+(i+1), activity.getName(), activity.getRole().getEnname(),  activity.getUser().getId(),candidateGroupList,new ArrayList<String>()));
            process.addFlowElement(createExclusiveGateway("createExclusiveGateway"+(i+1)));
            if (StringUtils.isNotBlank(activity.getReturnBack()) && !activity.getReturnBack().equals("0")){
                process.addFlowElement(createUserTask("audit"+(i+1), "重新申请", "", "${applyUserId}",new ArrayList<String>(),new ArrayList<String>()));
                process.addFlowElement(createExclusiveGateway("createExclusiveGatewayAudit"+(i+1)));
            }
        }


        process.addFlowElement(createEndEvent());
        process.addFlowElement(createSequenceFlow("startEvent", "task1", "", ""));
        /*process.addFlowElement(createSequenceFlow("task1", "createExclusiveGateway1", "", ""));
        process.addFlowElement(createSequenceFlow("createExclusiveGateway1", "endEvent", "不通过", "${pass=='2'}"));
        process.addFlowElement(createSequenceFlow("createExclusiveGateway1", "task2", "通过", "${pass=='1'}"));

        process.addFlowElement(createSequenceFlow("task2", "createExclusiveGateway2", "", ""));
        process.addFlowElement(createSequenceFlow("createExclusiveGateway2", "task1", "不通过", "${pass=='2'}"));
        process.addFlowElement(createSequenceFlow("createExclusiveGateway2", "task3", "通过", "${pass=='1'}"));
        process.addFlowElement(createSequenceFlow("task3", "createExclusiveGateway3", "", ""));
        process.addFlowElement(createSequenceFlow("createExclusiveGateway3", "task2", "不通过", "${pass=='2'}"));
        process.addFlowElement(createSequenceFlow("createExclusiveGateway3", "endEvent", "通过", "${pass=='1'}"));
        */
        for (int i = 0; i < list.size(); i++) {
            Activity activity = list.get(i);
            process.addFlowElement(createSequenceFlow("task"+(i+1), "createExclusiveGateway"+(i+1), "", ""));
            if (i == list.size()-1){
                process.addFlowElement(createSequenceFlow("createExclusiveGateway"+(i+1), "endEvent", "通过", "${pass}"));
                if (activity.getReturnBack().equals("1")){
                    process.addFlowElement(createSequenceFlow("createExclusiveGateway"+(i+1), "audit"+(i+1), "不通过", "${!pass}"));
                    process.addFlowElement(createSequenceFlow("audit"+(i+1), "createExclusiveGatewayAudit"+(i+1), "", ""));
                    if (i > 1){
                        process.addFlowElement(createSequenceFlow("createExclusiveGatewayAudit"+(i+1), "task"+i, "重新发起发起", "${pass}"));
                    }else {
                        process.addFlowElement(createSequenceFlow("createExclusiveGatewayAudit"+(i+1), "task"+1, "重新发起发起", "${pass}"));
                    }
                    process.addFlowElement(createSequenceFlow("createExclusiveGatewayAudit"+(i+1), "endEvent", "撤销", "${!pass}"));
                }else if (activity.getReturnBack().equals("2")){
                    process.addFlowElement(createSequenceFlow("createExclusiveGateway"+(i+1), "audit"+(i+1), "不通过", "${!pass}"));
                    process.addFlowElement(createSequenceFlow("audit"+(i+1), "createExclusiveGatewayAudit"+(i+1), "", ""));
                    process.addFlowElement(createSequenceFlow("createExclusiveGatewayAudit"+(i+1), "task"+1, "重新发起发起", "${pass}"));
                    process.addFlowElement(createSequenceFlow("createExclusiveGatewayAudit"+(i+1), "endEvent", "撤销", "${!pass}"));
                }else {
                    process.addFlowElement(createSequenceFlow("createExclusiveGateway"+(i+1), "endEvent", "不通过", "${!pass}"));
                }
            }else {
                process.addFlowElement(createSequenceFlow("createExclusiveGateway"+(i+1), "task"+(i+2), "通过", "${pass}"));
                if (activity.getReturnBack().equals("1")){
                    process.addFlowElement(createSequenceFlow("createExclusiveGateway"+(i+1), "audit"+(i+1), "不通过", "${!pass}"));
                    process.addFlowElement(createSequenceFlow("audit"+(i+1), "createExclusiveGatewayAudit"+(i+1), "", ""));
                    if (i > 1){
                        process.addFlowElement(createSequenceFlow("createExclusiveGatewayAudit"+(i+1), "task"+i, "重新发起发起", "${pass}"));
                    }else {
                        process.addFlowElement(createSequenceFlow("createExclusiveGatewayAudit"+(i+1), "task"+1, "重新发起发起", "${pass}"));
                    }
                    process.addFlowElement(createSequenceFlow("createExclusiveGatewayAudit"+(i+1), "endEvent", "撤销", "${!pass}"));
                }else if (activity.getReturnBack().equals("2")){
                    process.addFlowElement(createSequenceFlow("createExclusiveGateway"+(i+1), "audit"+(i+1), "不通过", "${!pass}"));
                    process.addFlowElement(createSequenceFlow("audit"+(i+1), "createExclusiveGatewayAudit"+(i+1), "", ""));
                    process.addFlowElement(createSequenceFlow("createExclusiveGatewayAudit"+(i+1), "task"+1, "重新发起发起", "${pass}"));
                    process.addFlowElement(createSequenceFlow("createExclusiveGatewayAudit"+(i+1), "endEvent", "撤销", "${!pass}"));
                }else {
                    process.addFlowElement(createSequenceFlow("createExclusiveGateway"+(i+1), "endEvent", "不通过", "${!pass}"));
                }
            }
        }

       // 2. Generate graphical information
        new BpmnAutoLayout(model).execute();

        // 3. Deploy the process to the engine
        Deployment deployment = repositoryService.createDeployment().addBpmnModel(PROCESSID+".bpmn", model).name(PROCESSID+"_deployment").deploy();

        // 4. Start a process instance
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(PROCESSID);

        // 5. Check if task is available
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).list();
        Assert.assertEquals(1, tasks.size());

        // 6. Save process diagram to a file
        // InputStream processDiagram = repositoryService.getProcessDiagram(processInstance.getProcessDefinitionId());
        // FileUtils.copyInputStreamToFile(processDiagram, new File("/deployments/"+PROCESSID+".png"));

        // 7. Save resulting BPMN xml to a file
        //  InputStream processBpmn = repositoryService.getResourceAsStream(deployment.getId(), PROCESSID+".bpmn");
        // FileUtils.copyInputStreamToFile(processBpmn,new File("/deployments/"+PROCESSID+".bpmn"));
        logger.info(".........end...");
    }

    protected static ProcessEngine getProcessEngine(){
        ProcessEngine processEngine=ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration()
                .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE)
                .setJdbcUrl(Global.getJdbcUrl())
                .setJdbcDriver(Global.getJdbcDriver())
                .setJdbcUsername(Global.getJdbcUserName())
                .setJdbcPassword(Global.getJdbcPassword())
                .setDatabaseSchemaUpdate("true")
                .setJobExecutorActivate(false)
                .buildProcessEngine();
        return processEngine;

    }

    /*任务节点*/
    protected static UserTask createUserTask(String id, String name, String candidateGroup,String assignee,List<String> candidateGroupList,List<String> users) {
        List<String> candidateGroups=new ArrayList<String>();
        if (candidateGroupList!=null && candidateGroupList.size()!=0){
            candidateGroups = candidateGroupList;
        }else {
            candidateGroups.add(candidateGroup);
        }
        UserTask userTask = new UserTask();
        userTask.setName(name);
        userTask.setId(id);
        userTask.setCandidateGroups(candidateGroups);
        if (users!=null && users.size()!=0){
            userTask.setCandidateUsers(users);
        }else {
            userTask.setAssignee(assignee);
        }
        return userTask;
    }

    /*连线*/
    protected static SequenceFlow createSequenceFlow(String from, String to,String name,String conditionExpression) {
        SequenceFlow flow = new SequenceFlow();
        flow.setSourceRef(from);
        flow.setTargetRef(to);
        flow.setName(name);
        if(StringUtils.isNotEmpty(conditionExpression)){
            flow.setConditionExpression(conditionExpression);
        }
        return flow;
    }

    /*排他网关*/
    protected static ExclusiveGateway createExclusiveGateway(String id) {
        ExclusiveGateway exclusiveGateway = new ExclusiveGateway();
        exclusiveGateway.setId(id);
        return exclusiveGateway;
    }

    /*开始节点*/
    protected static StartEvent createStartEvent() {
        StartEvent startEvent = new StartEvent();
        startEvent.setId("startEvent");
        startEvent.setInitiator("applyUserId");
        startEvent.setName("开始");
        return startEvent;
    }

    /*结束节点*/
    protected static EndEvent createEndEvent() {
        EndEvent endEvent = new EndEvent();
        endEvent.setId("endEvent");
        endEvent.setName("结束");
        return endEvent;
    }

}