package com.th.demo.controller.process;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.th.demo.model.system.Type;

import com.th.demo.tools.Tools;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;

import org.activiti.engine.repository.Model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

/**
 * Created by dell on 2018-11-12.
 */
@Controller
@RequestMapping(value = "/ProcessModel")
public class ModelController {

    @Autowired
    private RepositoryService repositoryService;
    String result = Type.FAIL;
    Gson gson = new Gson();
    @RequestMapping(value = "/query.do")
    @ResponseBody
    public String query(int page,
                          int rows,
                          String processName,
                          String userId,
                          HttpServletResponse response) throws IOException {

        PageHelper.startPage(page, rows);
        List<Model> list = repositoryService.createModelQuery().orderByCreateTime().desc().list();
        PageInfo<Model> pageInfo = new PageInfo<Model>(list);
        result = gson.toJson(pageInfo);
        return result;
    }


    /**
     * 创建模型
     */
    @RequestMapping("/create.do")
    public void create(
            String processName,
            String processKey,
            String processDescription,
            String userId,
            HttpServletRequest request, HttpServletResponse response) {
        try {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

            RepositoryService repositoryService = processEngine.getRepositoryService();

            ObjectMapper objectMapper = new ObjectMapper();
            ObjectNode editorNode = objectMapper.createObjectNode();
            editorNode.put("id", "canvas");
            editorNode.put("resourceId", "canvas");
            ObjectNode stencilSetNode = objectMapper.createObjectNode();
            stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
            editorNode.put("stencilset", stencilSetNode);
            Model modelData = repositoryService.newModel();

            ObjectNode modelObjectNode = objectMapper.createObjectNode();
            modelObjectNode.put(ModelDataJsonConstants.MODEL_ID, processKey);
            modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processName);
            modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
            String description = processDescription;
            modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
            modelData.setMetaInfo(modelObjectNode.toString());
            modelData.setName(processName);
            modelData.setKey(processKey);

            //保存模型
            repositoryService.saveModel(modelData);
            repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));


            // result = request.getContextPath() + "/modeler.html?modelId=" + modelData.getId();
            result = modelData.getId();
            Tools.out(response, result);
            // response.sendRedirect(request.getContextPath() + "/modeler.html?modelId=" + modelData.getId());
        } catch (Exception e) {
            System.out.println("创建模型失败：" + e.getMessage());
        }
    }

    /**
     * 部署model
     */
    @RequestMapping(value = "/deployModel.do")
    public void deployModel(String modelId,
                            String userId,
                            HttpServletRequest request, HttpServletResponse response) {
        try {
            Model modelData = repositoryService.getModel(modelId);

            ObjectNode modelNode = (ObjectNode) new ObjectMapper()
                    .readTree(repositoryService.getModelEditorSource(modelData.getId()));
            byte[] bpmnBytes = null;

            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            bpmnBytes = new BpmnXMLConverter().convertToXML(model);

            String processName = modelData.getName() + ".bpmn20.xml";


            Deployment deployment = repositoryService.createDeployment()
                    .name(modelData.getName())
                    .addString(processName, new String(bpmnBytes, "UTF-8"))
                    .deploy();

            System.out.println("部署成功，部署ID=" + deployment.getId());

            Tools.out(response, Type.SUCCESS);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 删除model
     */
    @RequestMapping(value = "/remove.do")
    public void delete(String modelId,
                       String userId,
                       HttpServletRequest request, HttpServletResponse response) {
        try {

            repositoryService.deleteModel(modelId);

            System.out.println("删除成功，modelId=" + modelId);

            Tools.out(response, Type.SUCCESS);
        } catch (Exception ex) {
            ex.printStackTrace();
            result = Type.FAIL + ex.getMessage();
        } finally {
            Tools.out(response, Type.SUCCESS);
        }
    }

}
