package com.yihu.hos.system.service;

import com.yihu.hos.common.constants.ContextAttributes;
import com.yihu.hos.config.BeanConfig;
import com.yihu.hos.core.datatype.ClassFileUtil;
import com.yihu.hos.core.file.FileUtil;
import com.yihu.hos.interceptor.LocalContext;
import com.yihu.hos.services.ServiceFlowEventService;
import com.yihu.hos.system.dao.FlowClassDao;
import com.yihu.hos.system.dao.FlowDao;
import com.yihu.hos.system.dao.FlowTempDao;
import com.yihu.hos.system.model.SystemServiceFlow;
import com.yihu.hos.system.model.SystemServiceFlowClass;
import com.yihu.hos.system.model.SystemServiceFlowTemp;
import com.yihu.hos.web.framework.constant.ServiceFlowConstant;
import com.yihu.hos.web.framework.model.ActionResult;
import com.yihu.hos.web.framework.model.DictItem;
import com.yihu.hos.web.framework.model.Result;
import com.yihu.hos.web.framework.model.bo.ServiceFlow;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统流程管理业务类
 *
 * @author HZY
 * @vsrsion 1.0
 * Created at 2016/8/19.
 */
@Service("flowManager")
public class FlowManager {
    public static final String BEAN_ID = "flowManager";
    @Autowired
    ServiceFlowEventService serviceFlowEventService;
    @Autowired
    private BeanConfig beanConfig;

    @Resource(name = "flowDao")
    private FlowDao flowDao;
    @Resource(name = FlowClassDao.BEAN_ID)
    private FlowClassDao flowClassDao;
    @Resource(name = FlowTempDao.BEAN_ID)
    private FlowTempDao flowTempDao;
    @Value("${hos.filesystem.url}")
    private String fsUrl;

    /**
     * 生成Route流程的java文件
     *
     * @param routeId      流程Id
     * @param className    模板类名
     * @param tempFilePath 模板文件路径
     * @param newCron      cron表达式
     * @return
     */
    public String genRouteJavaFile(String jobId, String routeId, String className, String tempFilePath, String newCron) {
        try {
            //TODO 临时文件夹
            String newFileName = className + routeId + ".java";
            String newFilePath = System.getProperty("java.io.tmpdir") + System.getProperty("file.separator")  + newFileName;
            String uploadUrl = fsUrl + "/" + tempFilePath;
            byte[] content = ClassFileUtil.down(uploadUrl);
            if (content == null) {
                return null;
            }

            String text = new String(content, StandardCharsets.UTF_8);
            if (text.contains("?cron=")) {
                text = text.replace("?cron=",routeId+"?cron=");//job名重新命名
                String oldStr = text.substring(text.indexOf("?cron=") + 6);
                String cron = oldStr.substring(0, oldStr.indexOf("\""));
                text = text.replace(cron, newCron);
            }
            //修改java类名
            if (text.contains(className)) {
                text = text.replace(className, className + routeId);//新类名规则=旧类名+routeId
            }
            //修改routeId；模板规则 routeId("routeId")
            text = text.replace("routeId(\"routeId\")", "routeId(\"" + routeId + "\")");
            //修改jobId；模板规则 "{\"jobId\": \"jobId\"}"
            text = text.replace("{\\\"jobId\\\": \\\"jobId\\\"}", "{\\\"jobId\\\": \\\"" + jobId + "\\\"}");
            boolean succ = FileUtil.writeFile(newFilePath, text, "UTF-8");
            if (succ) {
                newFileName = ClassFileUtil.uploadFile(beanConfig.getFsUrl(), new File(newFilePath), newFileName);
            } else {
                return null;
            }

            return newFileName;
        } catch (Exception e) {
            System.out.println("修改Route的java文件操作出错");
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 生成processor的java文件
     *
     * @param jobId        任务Id
     * @param routeId      流程Code
     * @param tempFilePath 模板文件名
     * @param className    模板类名
     * @return
     */
    public String genProcessorJavaFile(String jobId, String routeId, String tempFilePath, String className) {
        try {
            String newFileName = className + routeId + ".java";
            //TODO 临时文件夹设置
            String newFilePath = System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") +  newFileName;
            String uploadUrl = fsUrl + "/" + tempFilePath;
            byte[] content = ClassFileUtil.down(uploadUrl);
            if (content == null) {
                return null;
            }

            String text = new String(content, StandardCharsets.UTF_8);
            text = text.replace("jobId=jobId", "jobId=" + jobId);
            boolean succ = FileUtil.writeFile(newFilePath, text, "UTF-8");
            //TODO 上传到GridFS
            if (succ) {
                newFileName = ClassFileUtil.uploadFile(beanConfig.getFsUrl(), new File(newFilePath), newFileName);
                return newFileName;
            }
        } catch (Exception e) {
            System.out.println("生成processor的java文件操作出错");
            e.printStackTrace();
        }
        return null;
    }


    public Result getFlowList(Map<String, Object> params) throws Exception {
        return flowDao.getFlowList(params);
    }

    /**
     * @return List<ServiceFlow> 返回所有可运行流程
     * @throws Exception ...
     */
    public List<ServiceFlow> getServiceFlowList() throws Exception {
        List<ServiceFlow> serviceFlowList = new ArrayList<>();
        List<SystemServiceFlow> classFlowList = flowDao.getFlowList(ServiceFlowConstant.CLASS);
        for (SystemServiceFlow systemServiceFlow : classFlowList) {
            String tenant = LocalContext.getContext().getAttachment(ContextAttributes.TENANT_NAME);
            ServiceFlow serviceFlow = new ServiceFlow();
            serviceFlow.setRouteCode(systemServiceFlow.getCode());
            serviceFlow.setFlowType(systemServiceFlow.getFileType());
            serviceFlow.setTenant(tenant);
            List<SystemServiceFlowClass> classList = flowClassDao.getFlowClassByFlowId(systemServiceFlow.getId());
            ArrayList<ServiceFlow.HandleFile> handleFileList = new ArrayList<>();
            for (SystemServiceFlowClass flowClass : classList) {
                ServiceFlow.HandleFile handleFile = new ServiceFlow.HandleFile();
                handleFile.setFileType(ServiceFlowConstant.CLASS);
                handleFile.setClassName(flowClass.getClassName());
                handleFile.setPackageName(flowClass.getPackageName());
                handleFile.setFilePath(flowClass.getClassPath());
                handleFile.setUsage(flowClass.getType());
                handleFile.setRouteCode(serviceFlow.getRouteCode());

                handleFileList.add(handleFile);
            }
            serviceFlow.setHandleFiles(handleFileList);

            serviceFlowList.add(serviceFlow);
        }

        return serviceFlowList;
    }

        /* ===================================  flowClass 部分================================================*/


    public SystemServiceFlow getFlowById(Integer id) throws Exception {
        return flowDao.getEntity(SystemServiceFlow.class, id);
    }

    @Transactional
    public Result addFlow(SystemServiceFlow obj) throws Exception {
        obj.setCreateDate(new Date());
        flowDao.saveEntity(obj);

        if (ServiceFlowConstant.CLASS.equals(obj.getFileType())) {
            List<SystemServiceFlowClass> flowClassList = obj.getFlowClassArray();

            ServiceFlow serviceFlow = new ServiceFlow();
            serviceFlow.setRouteCode(obj.getCode());
            serviceFlow.setFlowType(ServiceFlowConstant.CLASS);

            for (SystemServiceFlowClass flowClass : flowClassList) {
                flowClass.setFlowId(obj.getId());
                flowDao.saveEntity(flowClass);

                ServiceFlow.HandleFile handleFile = new ServiceFlow.HandleFile();
                handleFile.setRouteCode(obj.getCode());
                handleFile.setFileType(ServiceFlowConstant.CLASS);
                handleFile.setPackageName(flowClass.getPackageName());
                handleFile.setClassName(flowClass.getClassName());
                handleFile.setFilePath(flowClass.getClassPath());
                handleFile.setUsage(flowClass.getType());
                serviceFlow.addHandleFile(handleFile);
            }

            serviceFlowEventService.serviceFlowAdded(serviceFlow);
        } else if (ServiceFlowConstant.JAVA.equals(obj.getFileType())) {
            List<SystemServiceFlowTemp> flowTempList = obj.getFlowTempArray();
            for (SystemServiceFlowTemp flowTemp : flowTempList) {
                flowTemp.setFlowId(obj.getId());
                flowDao.saveEntity(flowTemp);
            }
        }

        return Result.success("保存成功");
    }

    @Transactional
    public Result updateFlow(SystemServiceFlow obj) throws Exception {
        ServiceFlow serviceFlow = new ServiceFlow();

        SystemServiceFlow flow = flowDao.getEntity(SystemServiceFlow.class, obj.getId());
        flow.setCode(obj.getCode());
        flow.setName(obj.getName());
        flow.setPath(obj.getPath());
        flow.setChart(obj.getChart());
        flow.setValid(obj.getValid());
        flow.setFileType(obj.getFileType());


        if (ServiceFlowConstant.JAVA.equals(flow.getFileType())) {
            List<SystemServiceFlowTemp> flowTempList = obj.getFlowTempArray();
            boolean succ = flowTempDao.deleteFlowTempByFlowId(obj.getId());
            if (succ) {
                for (SystemServiceFlowTemp flowTemp : flowTempList) {
                    flowTempDao.saveEntity(flowTemp);
                }
            }
        } else if (ServiceFlowConstant.CLASS.equals(flow.getFileType())) {
            List<Integer> classIds = flowClassDao.getFlowClassIds(obj.getId());//原flowclass集合
            List<SystemServiceFlowClass> flowClassList = obj.getFlowClassArray();
            SystemServiceFlowClass flowClassRoute = null;
            serviceFlow.setRouteCode(obj.getCode());
            serviceFlow.setFlowType(ServiceFlowConstant.CLASS);
            for (SystemServiceFlowClass flowClass : flowClassList) {
                if (flowClass.getId() != null) {
                    classIds.remove(flowClass.getId());
                    flowClassDao.updateEntity(flowClass);
                } else {
                    if (!flowClass.getType().equals(ServiceFlowConstant.FLOW_TYPE_ROUTE)) {
                        flowClassDao.saveEntity(flowClass);
                    }
                }

                ServiceFlow.HandleFile handleFile = new ServiceFlow.HandleFile();
                handleFile.setRouteCode(obj.getCode());
                handleFile.setFileType(ServiceFlowConstant.CLASS);
                handleFile.setPackageName(flowClass.getPackageName());
                handleFile.setClassName(flowClass.getClassName());
                handleFile.setFilePath(flowClass.getClassPath());
                handleFile.setUsage(flowClass.getType());
                serviceFlow.addHandleFile(handleFile);

            }

            serviceFlowEventService.serviceFlowModifiedAdd(serviceFlow);

            //删除判断
            if (classIds != null && classIds.size() > 0) {
                for (Integer id : classIds) {
                    SystemServiceFlowClass flowClass = getFlowClassById(id);
                    flowClassDao.deleteEntity(flowClass);
                    if (flowClass.getType().equals(ServiceFlowConstant.FLOW_TYPE_ROUTE)) {
                        flowClassRoute = flowClass;
                        flowClassRoute.setIsUpdate("1");
                    }
                }
            }
        }

        flowDao.updateEntity(flow);


        return Result.success("更新成功");
    }

    @Transactional
    public Result deleteFlow(Integer id) throws Exception {
        SystemServiceFlow flow = flowDao.getEntity(SystemServiceFlow.class, id);
        if (flow == null) {
            return Result.error("删除流程失败");
        }
        ArrayList<ServiceFlow.HandleFile> handleFiles = new ArrayList<>();
        List<SystemServiceFlowClass> flowClassList = flowClassDao.getFlowClassByFlowId(id);
        if (ServiceFlowConstant.JAVA.equals(flow.getFileType())) {
            flowTempDao.deleteFlowTempByFlowId(id);
        } else {
            ServiceFlow serviceFlow = new ServiceFlow();
            serviceFlow.setRouteCode(flow.getCode());
            serviceFlow.setFlowType(ServiceFlowConstant.CLASS);
            for (SystemServiceFlowClass flowClass : flowClassList) {
                ServiceFlow.HandleFile handleFile = new ServiceFlow.HandleFile();
                handleFile.setRouteCode(flow.getCode());
                handleFile.setFileType(ServiceFlowConstant.JAVA);
                handleFile.setPackageName(flowClass.getPackageName());
                handleFile.setClassName(flowClass.getClassName());
                handleFile.setFilePath(flowClass.getClassPath());
                handleFile.setUsage(flowClass.getType());
                handleFiles.add(handleFile);

                flowClassDao.deleteEntity(flowClass);
            }
            serviceFlow.setHandleFiles(handleFiles);
            serviceFlowEventService.serviceFlowDelete(serviceFlow);

        }

        flowDao.deleteEntity(flow);
        return Result.success("删除流程成功");

    }


    public List<String> getFlowIdList(List<SystemServiceFlow> routeLis) throws Exception {
        List<String> routeCodes = new ArrayList<>();
        if (routeLis!=null && !routeLis.isEmpty()){
            routeCodes = routeLis.stream().filter(route -> ServiceFlowConstant.CLASS.equals(route.getFileType())).map(SystemServiceFlow::getCode).collect(Collectors.toList());
        }
        return routeCodes;
    }

    public Map<String,String> getFlowStausList(List<String> routeCodeLis) throws Exception {
        Map<String,String>  routeCodesStaus = new HashMap<>();
        if (routeCodeLis!=null && !routeCodeLis.isEmpty()){

        }
        return routeCodesStaus;
    }

    public List<SystemServiceFlowClass> getFlowClassByFlowId(Integer flowId) throws Exception {
        return flowClassDao.getFlowClassByFlowId(flowId);
    }

    public SystemServiceFlowClass getFlowClassById(Integer id) throws Exception {
        return flowClassDao.getEntity(SystemServiceFlowClass.class, id);
    }

    @Transactional
    public Result addFlowClass(SystemServiceFlowClass obj) throws Exception {
        flowDao.saveEntity(obj);
        return Result.success("保存成功");
    }

    @Transactional
    public Result updateFlowClass(SystemServiceFlowClass obj) throws Exception {
        return null;
    }

    @Transactional
    public boolean deleteFlowClassByFlowId(Integer flowId) {
        boolean succ = flowClassDao.deleteFlowClassByFlowId(flowId);
        return succ;
    }


    public List<SystemServiceFlowTemp> getFlowTempByFlowId(Integer id) throws Exception {
        return flowTempDao.getFlowTempByFlowId(id);
    }

    //TODO

    public boolean genFlewByflowTempId(Integer flowTempId) throws Exception {
        SystemServiceFlow flow = getFlowById(flowTempId);
        //生成新的route类

        //添加新processor记录
        return false;
    }


    /**
     * 发送MQ消息-更新路由
     *
     * @param flowCode  服务流程Code标识
     * @param flowClass
     * @param operate
     */
    public void sendUpdateMessage(String flowCode, SystemServiceFlowClass flowClass, String operate) {
        if ("1".equals(flowClass.getIsUpdate())) {
            ServiceFlow serviceFlow = new ServiceFlow();
            serviceFlow.setRouteCode(flowCode);
            serviceFlow.setFlowType(ServiceFlowConstant.CLASS);
            ServiceFlow.HandleFile handleFile = new ServiceFlow.HandleFile();
            handleFile.setRouteCode(flowCode);
            handleFile.setFileType(ServiceFlowConstant.CLASS);
            handleFile.setPackageName(flowClass.getPackageName());
            handleFile.setClassName(flowClass.getClassName());
            handleFile.setFilePath(flowClass.getClassPath());
            handleFile.setUsage(flowClass.getType());
            serviceFlow.addHandleFile(handleFile);

            switch (operate) {
                case ServiceFlowConstant.FLOW_OP_ADD:
                case ServiceFlowConstant.FLOW_OP_UPDATE:
                    serviceFlowEventService.serviceFlowModifiedAdd(serviceFlow);
                    break;
                case ServiceFlowConstant.FLOW_OP_DELETE:
                    serviceFlowEventService.serviceFlowModifiedReduce(serviceFlow);
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * 获取流程列表
     *
     * @param type 流程的文件类型
     * @return
     * @throws Exception
     */

    public ActionResult getFlowList(String type) throws Exception {
        List<SystemServiceFlow> flowList = flowDao.getFlowList(type);
        ActionResult re = new ActionResult();
        if (flowList != null && flowList.size() > 0) {
            List<DictItem> dictList = new ArrayList<>();
            for (SystemServiceFlow item : flowList) {
                DictItem dict = new DictItem();
                dict.setCode(item.getId().toString());
                dict.setValue(item.getName());
                dict.setExtend("");
                dictList.add(dict);
            }
            re.setData(dictList);
        }
        return re;
    }

    /**
     * 发送消息到broker，生成camel相关文件
     *
     * @param flowTempId
     * @param newCron
     * @throws Exception
     */
    public Integer genCamelFile(String jobId, Integer flowTempId, String newCron) throws Exception {
        Long timestamp = System.currentTimeMillis();
        //发送生成processor文件的消息
        Integer newFlowId = sendAddProcessor(jobId, flowTempId, timestamp, newCron);
        if (newFlowId != null) {
            //发送生成route文件的消息
//            newFlowId = sendAddRoute(flowTempId, newFlowId, newCron);
//            if (newFlowId != null) {
//                return newFlowId;
//            } else {
//                System.out.println("生成route文件失败");
//                return null;
//            }
            return newFlowId;
        } else {
            System.out.println("生成processor文件失败");
            return null;
        }
    }

    /**
     * 修改任务，修改camel相关文件
     *
     * @param flowId  流程ID
     * @param newCron 新cron
     * @return
     * @throws Exception
     */

    public Integer updateCamelFile(String jobId, Integer flowTempId, Integer flowId, String newCron) throws Exception {
         /* 修改route文件无需重新生成flowClass记录，文件名根据className+routeId 生成；*/
        List<SystemServiceFlowTemp> flowTempRouters = flowTempDao.getFlowTemps(flowTempId, ServiceFlowConstant.FLOW_TYPE_ROUTE);
        List<SystemServiceFlowTemp> flowTempProces = flowTempDao.getFlowTemps(flowTempId, ServiceFlowConstant.FLOW_TYPE_PROCESSOR);

        SystemServiceFlow flow = flowDao.getEntity(SystemServiceFlow.class, flowId);
        if (flow==null){
            //流程已经被删除，重新生成流程
            return genCamelFile(jobId,flowTempId,newCron);
        }
        //route模板文件记录是否存在。不存在就返回。
        if (!flowTempRouters.isEmpty()) {
            SystemServiceFlowTemp flowTemp = flowTempRouters.get(0);
            ArrayList<ServiceFlow.HandleFile> handleFiles = new ArrayList<>();
            ServiceFlow serviceFlow = new ServiceFlow();
            //新增processor记录
            for (SystemServiceFlowTemp process : flowTempProces) {
                String newPath = genProcessorJavaFile(jobId, flow.getCode(), process.getClassPath(), process.getClassName());
                if (newPath != null) {
                    //发送消息
                    serviceFlow.setRouteCode(flow.getCode());
                    serviceFlow.setFlowType(ServiceFlowConstant.CLASS);
                    ServiceFlow.HandleFile handleFile = new ServiceFlow.HandleFile();
                    handleFile.setRouteCode(flow.getCode());
                    handleFile.setFileType(ServiceFlowConstant.JAVA);
                    handleFile.setPackageName(process.getPackageName());
                    handleFile.setClassName(process.getClassName());
                    handleFile.setFilePath(newPath);
                    handleFile.setUsage(ServiceFlowConstant.FLOW_TYPE_PROCESSOR);
                    handleFiles.add(handleFile);
                    serviceFlow.setHandleFiles(handleFiles);
                } else {
                    System.out.println("生成processor的java文件过程出错");
                    return null;
                }
            }

            //生成新的route文件
            String newPath = genRouteJavaFile(jobId, flow.getCode(), flowTemp.getClassName(), flowTemp.getClassPath(), newCron);
            serviceFlow.setRouteCode(flow.getCode());
            serviceFlow.setFlowType(ServiceFlowConstant.JAVA);
            ServiceFlow.HandleFile handleFile = new ServiceFlow.HandleFile();
            handleFile.setRouteCode(flow.getCode());
            handleFile.setFileType(ServiceFlowConstant.JAVA);
            handleFile.setPackageName(flowTemp.getPackageName());
            handleFile.setClassName(flowTemp.getClassName() + flow.getCode());
            handleFile.setFilePath(newPath);
            handleFile.setUsage(ServiceFlowConstant.FLOW_TYPE_ROUTE);
            handleFiles.add(handleFile);
            serviceFlow.setHandleFiles(handleFiles);
            serviceFlowEventService.serviceFlowModifiedAdd(serviceFlow);
            return flowId;
        }
        return null;
    }

    /* *********************       发送消息方式生成文件   ********************************/
    public Integer sendAddRoute(Integer tempId, Integer flowId, String newCron) throws Exception {
        List<SystemServiceFlowTemp> flowTempRouters = flowTempDao.getFlowTemps(tempId, ServiceFlowConstant.FLOW_TYPE_ROUTE);
        SystemServiceFlow newFlow = getFlowById(flowId);

        //route模板文件记录是否存在。不存在就返回。
        if (!flowTempRouters.isEmpty()) {
            SystemServiceFlowTemp flowTemp = flowTempRouters.get(0);
            StringBuilder basePath = new StringBuilder();
            ;
            if (flowTemp.getPackageName() != null) {
                String packagePath[] = flowTemp.getPackageName().split("\\.");
                for (int i = 0; i < packagePath.length; i++) {
                    basePath.append(packagePath[i]).append("/");
                }
            }

            //新增processor记录
            String newPath = genRouteJavaFile("", newFlow.getCode(), flowTemp.getClassName(), flowTemp.getClassPath(), newCron);
            SystemServiceFlowClass newFlowClass = new SystemServiceFlowClass();
            newFlowClass.setPackageName(flowTemp.getPackageName());
            newFlowClass.setClassName(flowTemp.getClassName() + newFlow.getCode());
            newFlowClass.setClassPath(flowTemp.getClassPath());
            newFlowClass.setFlowId(newFlow.getId());
            newFlowClass.setType(ServiceFlowConstant.FLOW_TYPE_ROUTE);
            flowClassDao.saveEntity(newFlowClass);
            newFlowClass.setIsUpdate("1");


            if (newPath != null) {
                ServiceFlow serviceFlow = new ServiceFlow();
                serviceFlow.setRouteCode(newFlow.getCode());
                serviceFlow.setFlowType(ServiceFlowConstant.CLASS);
                ServiceFlow.HandleFile handleFile = new ServiceFlow.HandleFile();
                handleFile.setRouteCode(newFlow.getCode());
                handleFile.setFileType(ServiceFlowConstant.JAVA);
                handleFile.setPackageName(flowTemp.getPackageName());
                handleFile.setClassName(flowTemp.getClassName() + newFlow.getCode());
                handleFile.setFilePath(newPath);
                handleFile.setUsage(ServiceFlowConstant.FLOW_TYPE_ROUTE);
                ArrayList<ServiceFlow.HandleFile> handleFiles = new ArrayList<>();
                handleFiles.add(handleFile);
                serviceFlow.setHandleFiles(handleFiles);
                serviceFlowEventService.serviceFlowModifiedAdd(serviceFlow);
                return newFlow.getId();
            } else {
                System.out.println("生成route的java文件过程出错");
                return null;
            }
        }

        return null;
    }

    public Integer sendAddRoute(String code, String name, String javaName, String packageName, String fileInfo) throws Exception {

        String fileName = javaName + ".java";
        String filePath = this.getClass().getProtectionDomain().getClassLoader().getResource("").getPath() + "temp/" + fileName;
        boolean succ = FileUtil.writeFile(filePath, fileInfo, "UTF-8");
        String path = "";
        if (succ) {
            path = ClassFileUtil.uploadFile(beanConfig.getFsUrl(), new File(filePath), fileName);
        } else {
            return null;
        }

        if (fileName != null) {
            SystemServiceFlow systemServiceFlow = new SystemServiceFlow();
            systemServiceFlow.setName(name);
            systemServiceFlow.setCode(code);
            systemServiceFlow.setCreateDate(new Date());
            systemServiceFlow.setValid(1);
            systemServiceFlow.setFileType(ServiceFlowConstant.JAVA);
            flowDao.saveEntity(systemServiceFlow);

            ServiceFlow serviceFlow = new ServiceFlow();
            serviceFlow.setRouteCode(code);
            serviceFlow.setFlowType(ServiceFlowConstant.CLASS);
            ServiceFlow.HandleFile handleFile = new ServiceFlow.HandleFile();
            handleFile.setRouteCode(code);
            handleFile.setFileType(ServiceFlowConstant.JAVA);
            handleFile.setPackageName(packageName);
            handleFile.setClassName(javaName);
            handleFile.setFilePath(path);
            handleFile.setUsage(ServiceFlowConstant.FLOW_TYPE_ROUTE);
            ArrayList<ServiceFlow.HandleFile> handleFiles = new ArrayList<>();
            handleFiles.add(handleFile);
            serviceFlow.setHandleFiles(handleFiles);
            serviceFlowEventService.serviceFlowAdded(serviceFlow);

            SystemServiceFlowClass flowClass = new SystemServiceFlowClass();
            flowClass.setPackageName(packageName);
            flowClass.setClassName(javaName);
            flowClass.setClassPath(path);
            flowClass.setFlowId(systemServiceFlow.getId());
            flowClass.setType(ServiceFlowConstant.FLOW_TYPE_ROUTE);
            flowClass.setIsUpdate("1");
            flowClassDao.saveEntity(flowClass);

            return systemServiceFlow.getId();
        } else {
            System.out.println("生成route的java文件过程出错");
            return null;
        }
    }

    public Integer sendAddProcessor(String jobId, Integer flowId, Long timestamp, String newCron) throws Exception {
        List<SystemServiceFlowTemp> flowTempRouters = flowTempDao.getFlowTemps(flowId, ServiceFlowConstant.FLOW_TYPE_ROUTE);
        List<SystemServiceFlowTemp> flowTempProces = flowTempDao.getFlowTempByFlowId(flowId);
        SystemServiceFlow oldFlow = getFlowById(flowId);

        //route模板文件记录是否存在。不存在就返回。
        if (!flowTempRouters.isEmpty()) {

            //成功生成文件后，添加flow和flowclass记录
            SystemServiceFlow newFlow = new SystemServiceFlow();
            newFlow.setName(oldFlow.getName() + timestamp);
            newFlow.setCode(oldFlow.getCode() + timestamp);
            newFlow.setChart(oldFlow.getChart());
            newFlow.setValid(1);
            newFlow.setCreateDate(new Date());
            newFlow.setFileType(ServiceFlowConstant.CLASS);
            flowDao.saveEntity(newFlow);
            ArrayList<ServiceFlow.HandleFile> handleFiles = new ArrayList<>();

            //新增processor记录
            ServiceFlow serviceFlow = new ServiceFlow();
            serviceFlow.setRouteCode(newFlow.getCode());
            serviceFlow.setFlowType(ServiceFlowConstant.JAVA);
            for (SystemServiceFlowTemp process : flowTempProces) {
                StringBuilder proPath = new StringBuilder();
                if (process.getPackageName() != null) {
                    //生成“/"分割的包名
                    String packagePath[] = process.getPackageName().split("\\.");
                    for (int i = 0; i < packagePath.length; i++) {
                        proPath.append(packagePath[i]).append("/");
                    }
                }

                SystemServiceFlowClass processClass = new SystemServiceFlowClass();
                processClass.setPackageName(process.getPackageName());
                processClass.setClassName(process.getClassName());
                processClass.setClassPath(processClass.getClassPath());
                processClass.setFlowId(newFlow.getId());
                processClass.setType(process.getType());
                processClass.setIsUpdate("1");

                //发送消息
                ServiceFlow.HandleFile handleFile = new ServiceFlow.HandleFile();
                handleFile.setRouteCode(newFlow.getCode());
                handleFile.setFileType(ServiceFlowConstant.JAVA);
                handleFile.setPackageName(processClass.getPackageName());
                handleFile.setUsage(processClass.getType());

                String newPath = null;
                if (ServiceFlowConstant.FLOW_TYPE_PROCESSOR.equals(process.getType())) {
                    newPath = genProcessorJavaFile(jobId, newFlow.getCode(), process.getClassPath(), process.getClassName());
                    handleFile.setClassName(processClass.getClassName());
                } else {
                    newPath = genRouteJavaFile(jobId, newFlow.getCode(), process.getClassName(), process.getClassPath(), newCron);
                    handleFile.setClassName(processClass.getClassName() + newFlow.getCode());
                }

                if (newPath != null) {
                    handleFile.setFilePath(newPath);
                    handleFiles.add(handleFile);
                    processClass.setClassPath(newPath);
                    flowClassDao.saveEntity(processClass);
                } else {
                    System.out.println("生成processor的java文件过程出错");
                    return null;
                }
            }

            serviceFlow.setHandleFiles(handleFiles);
            serviceFlowEventService.serviceFlowAdded(serviceFlow);

            return newFlow.getId();
        }

        return null;
    }

    /**
     * 服务启动/暂停
     *
     * @param flowId 流程ID
     * @param oper   服务操作；1：启动；0：暂停
     * @return
     * @throws Exception
     */
    public boolean serviceOpenOrPause(Integer flowId, Integer oper) throws Exception {
        SystemServiceFlow flow = flowDao.getEntity(SystemServiceFlow.class, flowId);
        if (flow != null) {
            List<SystemServiceFlowClass> flowClassList = flowClassDao.getFlowClassByFlowId(flowId);
            //route模板文件记录是否存在。不存在就返回。
            ArrayList<ServiceFlow.HandleFile> handleFiles = new ArrayList<>();
            //新增processor记录
            ServiceFlow serviceFlow = new ServiceFlow();
            serviceFlow.setRouteCode(flow.getCode());
            serviceFlow.setFlowType(ServiceFlowConstant.CLASS);
            for (SystemServiceFlowClass flowClass : flowClassList) {
//                String deName = DES.decrypt(flowClass.getClassPath(), DES.COMMON_PASSWORD);//吉阿米果的文件名
                //发送消息
                ServiceFlow.HandleFile handleFile = new ServiceFlow.HandleFile();
                handleFile.setRouteCode(flow.getCode());
                handleFile.setFileType(ServiceFlowConstant.CLASS);
                handleFile.setPackageName(flowClass.getPackageName());
                handleFile.setClassName(flowClass.getClassName());
                handleFile.setFilePath(flowClass.getClassPath());
                handleFile.setUsage(ServiceFlowConstant.FLOW_TYPE_PROCESSOR);
                handleFiles.add(handleFile);
            }
            serviceFlow.setHandleFiles(handleFiles);
            if (1 == oper) {
                serviceFlowEventService.serviceFlowStarted(serviceFlow);
            } else if (0 == oper) {
                serviceFlowEventService.serviceFlowStopped(serviceFlow);
            } else {
                return false;
            }
            return true;
        } else {
            return false;
        }
    }

    /**
     * 解析文件 包名和类名
     *
     * @param file java文件流
     * @return
     */
    public Map<String, String> uploadAndParse(File file) {
        Map<String, String> result = null;
        String text = null;
        String packageName = null;
        String className = StringUtils.substringBefore(file.getName(), ".");
        if (file.getName().contains(".class")) {
            try {//class文件解析
                text = parseClassFile(file);
                packageName = StringUtils.substringBefore(StringUtils.substringAfter(text, "public class "), "." + className);//通过javap解析的结构不一样
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {//java文件解析
            text = FileUtil.readFileText(file);
            packageName = StringUtils.substringAfter(StringUtils.substringBefore(text, ";"), "package ");
        }
        result = new HashMap<>();
        result.put("package", packageName);
        result.put("class", className);


        return result;
    }

    /**
     * 解析class文件
     *
     * @param file
     * @return
     * @throws Exception
     */
    public String parseClassFile(File file) throws Exception {
        String path = file.getAbsolutePath();
        String command = "javap " + path;
        Process ps = Runtime.getRuntime().exec(command);
        String result = FileUtil.readFileText(ps.getInputStream());
        System.out.println(result);
        return result;

    }


}
