package io.renren.modules.sys.controller;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.argoproj.workflow.ApiException;
import io.argoproj.workflow.models.*;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1Container;
import io.kubernetes.client.openapi.models.V1EnvVar;
import io.kubernetes.client.openapi.models.V1ObjectMeta;
import io.minio.PutObjectOptions;
import io.minio.errors.*;
import io.renren.common.utils.*;

import io.renren.modules.sys.entity.VisiWorkflowEntity;
import io.renren.modules.sys.service.VisiWorkflowService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.stream.Collectors;

import static io.renren.common.utils.ShiroUtils.getUserId;

/**
 * 工作流提交及查询
 *
 * @author Zhang
 * @version 3.0.0
 * @since JDK1.8
 */
@RestController
@RequestMapping("visi/visiworkflow")
public class VisiWorkflowController extends AbstractController {

    //20211108
    @Autowired
    private VisiWorkflowService visiWorkflowService;
    @Value("${datasetLocation}")
    String datasetLocation;


    /**
     * 列表
     *
     * @param params 页面设置信息
     * @return 工作流列表
     */
    @RequestMapping("/list")
//    @RequiresPermissions("visi:visiworkflow:list")
    public R list(@RequestParam Map<String, Object> params) {
//        PageUtils page = visiWorkflowService.queryPage(params);
        //只有超级管理员，才能查看所有模板列表
        if(getUserId() != Constant.SUPER_ADMIN){
            params.put("currentUserId", getUserId());
        }
        PageUtils page = visiWorkflowService.queryPageOnUse(params);

        return R.ok().put("page", page);
    }
    /**
     * 删除
     */
    @RequestMapping("/delete")
//    @RequiresPermissions("generator:visiworkflow:delete")
    public R delete(@RequestBody Long[] workflowIds){
        visiWorkflowService.removeByIds(Arrays.asList(workflowIds));

        return R.ok();
    }

    /**
     * 保存
     *
     * @param visiWorkflow 工作流具体内容
     * @return 提示信息
     */
    @RequestMapping("/save")
//    @RequiresPermissions("sys:visiworkflow:save")
    public R save(@RequestBody VisiWorkflowEntity visiWorkflow) {
        visiWorkflowService.saveOrUpdate(visiWorkflow);

        return R.ok();
    }

    //应用JSONObject接收数据

    /**
     * 接收前端上传的文件，保存到minio中，返回文件地址
     *
     * @param request 文件传输请求
     * @return 文件url
     * @throws IOException
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws InsufficientDataException
     * @throws InvalidResponseException
     * @throws ErrorResponseException
     * @throws XmlParserException
     * @throws InvalidBucketNameException Minio的bucketname无效时
     * @throws InternalException
     */
    @RequestMapping("/savefile")
    public R Savefile(MultipartHttpServletRequest request) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, InvalidResponseException, ErrorResponseException, XmlParserException, InvalidBucketNameException, InternalException {


        Map<String, MultipartFile> list = request.getFileMap();
        System.out.println("savefile");
        System.out.println(list);
        Set<String> keys = list.keySet();
        JSONObject jsonfileurl = new JSONObject();
        for (String key : keys) {

            MultipartFile file = list.get(key);
            System.out.println(file.getOriginalFilename());
//            System.out.println();
            try {
                MinIoUtils.createBucket("visiarguartifact");
            } catch (RegionConflictException e) {
                e.printStackTrace();
            }
//            MinIoUtils.uploadMultipartFile(file,"algorithm","alg"+algId+"/version"+versionService.getMaxId()+"/"+file.getOriginalFilename());
            MinIoUtils.uploadMultipartFile(file, "visiarguartifact", "argoworkflow" + "/" + file.getOriginalFilename());
            String fileurl = MinIoUtils.getFileUrl("visiarguartifact", "argoworkflow" + "/" + file.getOriginalFilename());
            System.out.println("fileurl: " + fileurl);
            jsonfileurl.put(key, fileurl);

//            fileurls.add(fileurl);
        }
        return R.ok().put("jsonfileurl", jsonfileurl);

//        List<MultipartFile> files=request.getFiles("file");
//        System.out.println("savefile");
//        System.out.println(files);
//        List<String> fileurls = new ArrayList<String>();
//        for(MultipartFile file:files){
////            if(file.isEmpty())  break;
//            System.out.println(file.getOriginalFilename());
////            MinIoUtils.uploadMultipartFile(file,"algorithm","alg"+algId+"/version"+versionService.getMaxId()+"/"+file.getOriginalFilename());
//            MinIoUtils.uploadMultipartFile(file,"visiarguartifact","argoworkflow"+"/"+file.getOriginalFilename());
//            String fileurl = MinIoUtils.getFileUrl("visiarguartifact", "argoworkflow" + "/" + file.getOriginalFilename());
//            System.out.println("fileurl: "+fileurl);
//            fileurls.add(fileurl);
//        }
//
//        return R.ok().put("fileurls",fileurls);

//        List<MultipartFile> files=request.getFiles("file");
//        System.out.println("savefile");
//        System.out.println(files);
//        List<String> fileurls = new ArrayList<String>();
//        for(MultipartFile file:files){
////            if(file.isEmpty())  break;
//            System.out.println(file.getOriginalFilename());
////            MinIoUtils.uploadMultipartFile(file,"algorithm","alg"+algId+"/version"+versionService.getMaxId()+"/"+file.getOriginalFilename());
//            MinIoUtils.uploadMultipartFile(file,"visiarguartifact","argoworkflow"+"/"+file.getOriginalFilename());
//            String fileurl = MinIoUtils.getFileUrl("visiarguartifact", "argoworkflow" + "/" + file.getOriginalFilename());
//            System.out.println("fileurl: "+fileurl);
//            fileurls.add(fileurl);
//        }
//
//        return R.ok().put("fileurls",fileurls);
    }


    //应用JSONObject接收数据

    /**
     * 接收前端上传的文件，保存到minio中，返回文件地址
     *
     * @param request 文件传输请求
     * @return 文件url
     * @throws IOException
     * @throws InvalidKeyException
     * @throws NoSuchAlgorithmException
     * @throws InsufficientDataException
     * @throws InvalidResponseException
     * @throws ErrorResponseException
     * @throws XmlParserException
     * @throws InvalidBucketNameException
     * @throws InternalException
     */
    @RequestMapping("/saveinputfile")
    public R Saveinputfile(MultipartHttpServletRequest request) throws IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, InvalidResponseException, ErrorResponseException, XmlParserException, InvalidBucketNameException, InternalException {


        Map<String, MultipartFile> list = request.getFileMap();
        System.out.println("savefile");
        System.out.println(list);
        Set<String> keys = list.keySet();
        JSONObject jsonfileurl = new JSONObject();
        for (String key : keys) {

            MultipartFile file = list.get(key);
            System.out.println(file.getOriginalFilename());
//            MinIoUtils.uploadMultipartFile(file,"algorithm","alg"+algId+"/version"+versionService.getMaxId()+"/"+file.getOriginalFilename());
            MinIoUtils.uploadMultipartFile(file, "visiarguartifact", "argoworkflow" + "/" + file.getOriginalFilename());
            String fileurl = MinIoUtils.getFileUrl("visiarguartifact", "argoworkflow" + "/" + file.getOriginalFilename());
            System.out.println("fileurl: " + fileurl);
            //设置文件名称  文件地址
            jsonfileurl.put(file.getOriginalFilename(), fileurl);

//            fileurls.add(fileurl);
        }
        return R.ok().put("jsonfileurl", jsonfileurl);

    }

    /**
     * 创建workflowTemplate,提交workflow
     */

    //应用JSONObject接收数据

    /**
     * 创建WorkflowTemplate，提交Workflow
     *
     * @param  params
     * @return 提示信息
     */
    @RequestMapping("/submit")
//    public R Submit(@RequestBody JSONObject jsonObject) {
    public R Submit(@RequestBody Map<String, Object> params) {
        System.out.println(params.toString());
        System.out.println(params.get("addorupdate"));
        Boolean addorupdate = Boolean.valueOf(params.get("addorupdate").toString());
        System.out.println("//true表示update,新增  false表示add "+ addorupdate);
        Long  workflowId = null;
        if(addorupdate){
            workflowId = Long.parseLong(params.get("workflowId").toString());//工作流名称
        }

        String experimentName = params.get("experimentName").toString();
        //true表示update,新增  false表示add

        Object graphJson = params.get("graphJson");
        JSONObject jsonObject = JSONObject.parseObject(graphJson.toString());
        //连接argo
        //创建Workflowtemplate

//        ApiClient defaultClient = Configuration.getDefaultApiClient();
//        defaultClient.setBasePath("http://192.168.222.100:32639");
////        defaultClient.setBasePath("https://150.158.138.99:31547");
////        defaultClient.setBasePath("https://182.92.79.148:31828");
//        defaultClient.setVerifyingSsl(false);
//        WorkflowTemplateServiceApi apiInstance = new WorkflowTemplateServiceApi(defaultClient);


//        String namespace = "default"; // String |
        String namespace = "argo"; // String |
        WorkflowTemplateCreateRequest body = new WorkflowTemplateCreateRequest(); // WorkflowTemplateCreateRequest |

        //2.1createOptions	CreateOptions		[optional]
        //2.2namespace	String		[optional]
        body.setNamespace(namespace);
        //2.3template	WorkflowTemplate		[optional]
        WorkflowTemplate workflowTemplate1 = new WorkflowTemplate();

        //2.3.1 apiVersion
        workflowTemplate1.apiVersion("argoproj.io/v1alpha1");
        //2.3.2 kind
        //workflowTemplate1.kind("Workflow");
        workflowTemplate1.setKind("WorkflowTemplate");
        //2.3.3 Metadata
        V1ObjectMeta v1ObjectMeta = new V1ObjectMeta();
        //2.3.3.1
        //20210907    zhang   每一个流程自行设置  英文名称    暂时先固定
        v1ObjectMeta.setGenerateName("hello-world-parameters-");//此处name是设置一个然后每次随机添加后缀，创建完返回名称


        //2.3.3.2
        v1ObjectMeta.setNamespace(namespace);
        //workflowTemplate1.metadata(v1ObjectMeta);
        workflowTemplate1.setMetadata(v1ObjectMeta);

        //2.3.4 spec
        WorkflowTemplateSpec workflowTemplateSpec = new WorkflowTemplateSpec();
        workflowTemplateSpec.setEntrypoint("dagtest");//入口位置，设置Template类型为DAG的模板名称   自拟/固定？
        //参数
//        Arguments arguments = new Arguments();
//        Parameter parameter = new Parameter();
//        parameter.setName("message");
//        parameter.setValue("hello");
//        arguments.addParametersItem(parameter);
//        workflowTemplateSpec.setArguments(arguments);

        //各个Template
        List<Template> templateslist = new LinkedList<Template>();
        Template dagtemp = new Template();
        dagtemp.setName("dagtest");   //是否固定？与 入口位置相同
        DAGTemplate dagTemplate = new DAGTemplate();

        List<DAGTask> taskslist = new LinkedList<DAGTask>();

        //获取日志部分
        //建立前端节点ip与Template 中的 template name 之间的对应关系，除dag之外的所有template
        Map<String, String> idTemplateNameMap = new HashMap<String, String>();


        //20210721
        //获取前端流程数据
//        JSONObject cells = jsonObject.getJSONObject("cells");
        //获取各个cell数据
        JSONArray cellsarray = jsonObject.getJSONArray("cells");
        System.out.println(cellsarray);


        //节点id 对应相应的dagtask   name
        Map<String, String> idtempname = new HashMap<String, String>();
        for (int i = 0; i < cellsarray.size(); i++) {
            //判断若为rect,则表示节点，存储template数据，创建新的Template，并加入DAGTAsk中
            if (cellsarray.getJSONObject(i).getString("shape").equals("template-node")) {

                String rectid = cellsarray.getJSONObject(i).getString("id");


                //获取数据
                JSONObject rectdata = cellsarray.getJSONObject(i).getJSONObject("data");//获取你想获取的内容
                //templateName  --存放于template中
                String templateName = rectdata.getString("templateName");
//                Integer templaterandom = new Random().nextInt(100);
//                templateName = templateName+templaterandom.toString();//名称后添加随机数，确保有两个相同节点时，能正确执行
//                变更为前端添加随机数
//                templateName: this.algorithmdataList[i].algonodeName+Math.floor(Math.random() * 100),

                //templateImage   --存放于  V1Container 中
                String templateImage = rectdata.getString("templateImage");
                //templateCommand    List<String> command    --存放于  V1Container 中
                List<String> command = new LinkedList<String>();
                JSONObject templateCommand = rectdata.getJSONObject("templateCommand");
                //然后通过循环遍历出的key值
                for (Map.Entry<String, Object> entry : templateCommand.entrySet()) {
                    command.add(entry.getValue().toString());
                }

                //templateArgs   --存放于  V1Container 中
                List<String> args = new LinkedList<String>();
                JSONObject templateargs = rectdata.getJSONObject("templateArgs");
                //然后通过循环遍历出的key值
                for (Map.Entry<String, Object> entry : templateargs.entrySet()) {
                    String value = entry.getValue().toString();
                    args.add(entry.getValue().toString());
                }

                //参数   --类型暂未确定
                //inputsparameters    --存放于template中
                List<Parameter> inputsparalist = new LinkedList<Parameter>();
                List<V1EnvVar> envlist = new LinkedList<V1EnvVar>();    //20211208    将parameter添加为环境变量

                //0312添加spark环境变量
                V1EnvVar envvarsparkrest = new V1EnvVar();
                envvarsparkrest.setName("SPARKMASTERREST");
                envvarsparkrest.setValue(ArgoUtils.getSparkMasterRest());
                envlist.add(envvarsparkrest);
                V1EnvVar envvarsparkmaster = new V1EnvVar();
                envvarsparkmaster.setName("SPARKMASTER");
                envvarsparkmaster.setValue(ArgoUtils.getSparkMaster());
                envlist.add(envvarsparkmaster);
                V1EnvVar envvarsparkhdfsurl = new V1EnvVar();
                envvarsparkhdfsurl.setName("SPARKHDFSURL");
                envvarsparkhdfsurl.setValue(ArgoUtils.getSparkHdfsurl());
                envlist.add(envvarsparkhdfsurl);

                V1EnvVar envvarsparkYarnAddress = new V1EnvVar();
                envvarsparkYarnAddress.setName("SPARKYARNADDRESS");
                envvarsparkYarnAddress.setValue(ArgoUtils.getSparkYarnAddress());
                envlist.add(envvarsparkYarnAddress);
                V1EnvVar envvarsparkYarnJARS = new V1EnvVar();
                envvarsparkYarnJARS.setName("SPARKYARNJARS");
                envvarsparkYarnJARS.setValue(ArgoUtils.getSparkYarnJARS());
                envlist.add(envvarsparkYarnJARS);


                JSONArray inputsparameters = rectdata.getJSONArray("inputsparameters");
//                List<String> inputsparam = new LinkedList<String>();
                for (int j = 0; j < inputsparameters.size(); j++) {
                    String paramname = inputsparameters.getJSONObject(j).getString("paraname");
                    Parameter parameter = new Parameter();
                    parameter.setName(paramname);
                    inputsparalist.add(parameter);
//                    inputparam.add(inputparameters.getJSONObject(j).getString("name"));

                    V1EnvVar envvar = new V1EnvVar();
                    envvar.setName(paramname.toUpperCase());
                    envvar.setValue("{{inputs.parameters." + paramname + "}}");
                    envlist.add(envvar);
                }

                //20210915   zhang   inputs   artifacts
                //inputs  artifacts    --存放于template中
                List<Artifact> inputsartilist = new LinkedList<Artifact>();
                JSONArray inputsartifacts = rectdata.getJSONArray("inputsartifacts");
                for (int j = 0; j < inputsartifacts.size(); j++) {
                    String artiname = inputsartifacts.getJSONObject(j).getString("paraname");
                    String artipath = inputsartifacts.getJSONObject(j).getString("parapath");
                    Artifact artifact = new Artifact();

                    artifact.setName(artiname);
                    artifact.setPath(artipath);
                    inputsartilist.add(artifact);

                }

                Inputs inputs = new Inputs();
                inputs.setParameters(inputsparalist);
                inputs.setArtifacts(inputsartilist);

                //20210915   zhang   output
                //outputsparameters    --存放于template中
                List<Parameter> outputsparalist = new LinkedList<Parameter>();
                JSONArray outputsparameters = rectdata.getJSONArray("outputsparameters");
                for (int j = 0; j < outputsparameters.size(); j++) {
                    String outparamname = outputsparameters.getJSONObject(j).getString("paraname");
                    //20211127  发现此处没有给赋值,可能是value 或是valuefrom------要求为valuefrom
//                    String outparavalue = outputsparameters.getJSONObject(j).getString("paravalue");
                    String outparavaluefrom = outputsparameters.getJSONObject(j).getString("valuefrom");

                    Parameter outparameter = new Parameter();
                    outparameter.setName(outparamname);

                    //此部分均需进行判断后，
                    //------------------------新加判断字符串是否为空，然后赋值   value,    未完成
//                    outparameter.setValue(outparavalue);
                    //-------------------------判断valuefrom是否为空，设置ValueFrom
                    ValueFrom valuefrom = new ValueFrom();
                    valuefrom.setPath(outparavaluefrom);
                    outparameter.setValueFrom(valuefrom);

                    outputsparalist.add(outparameter);
//                    inputparam.add(inputparameters.getJSONObject(j).getString("name"));
                }

                //20210915   zhang   outputs   artifacts
                //outputs  artifacts    --存放于template中
                List<Artifact> outputartilist = new LinkedList<Artifact>();

                JSONArray outputsartifacts = rectdata.getJSONArray("outputsartifacts");
                for (int j = 0; j < outputsartifacts.size(); j++) {
                    String outartiname = outputsartifacts.getJSONObject(j).getString("paraname");
//                    String outartipath = outputsartifacts.getJSONObject(j).getString("path");
                    String outartipath = outputsartifacts.getJSONObject(j).getString("valuefrom");
                    Artifact outartifact = new Artifact();

                    //设置输出artifact 存档策略
                    ArchiveStrategy archiveStrategy = new ArchiveStrategy();
                    Object none = new Object();
                    archiveStrategy.setNone(none);
                    outartifact.setArchive(archiveStrategy);

                    outartifact.setName(outartiname);
                    outartifact.setPath(outartipath);
                    outputartilist.add(outartifact);

                }

                Outputs outputs = new Outputs();
                outputs.setParameters(outputsparalist);
                outputs.setArtifacts(outputartilist);


                //argumentsparameters   --存放于DAGTask中
                List<Parameter> argumparalist = new LinkedList<Parameter>();
                JSONArray argumentsparameters = rectdata.getJSONArray("argumentsparameters");
//                List<String> argumentsparam = new LinkedList<String>();
//                List<String> argumentsvalue = new LinkedList<String>();
                for (int j = 0; j < argumentsparameters.size(); j++) {
                    //自输入
                    String arguparaname = argumentsparameters.getJSONObject(j).getString("paraname");
                    String arguparavalue = argumentsparameters.getJSONObject(j).getString("paravalue");
                    //{{tasks.generate-parameter.outputs.parameters.hello-param}}
                    //20210909    zhang    需要对arguments的value 值做处理
                    Parameter argupara = new Parameter();
                    argupara.setName(arguparaname);
                    argupara.setValue(arguparavalue);

//                    //引用其他节点--前端已处理为  {{tasks.generate-parameter.outputs.parameters.hello-param}}方式
//                    if(argumentsparameters.getJSONObject(j).getString("valuefrom").length()!=0){
//                        String arguparafrom = argumentsparameters.getJSONObject(j).getString("valuefrom");
//                        argupara.setValue(arguparafrom);
//                        System.out.println(argupara.getValue());
//                    }
                    //更改引用节点为多选 ，多个进行拼接
                    //示例：  ['{{tasks.getsum43.outputs.parameters.result}}', '{{tasks.getsum344.outputs.parameters.result}}']
                    if (argumentsparameters.getJSONObject(j).getJSONArray("valuefrom").size() != 0) {
                        JSONArray valuefrom1 = argumentsparameters.getJSONObject(j).getJSONArray("valuefrom");
                        StringBuffer paravaluefrom = new StringBuffer();
                        for (int k = 0; k < valuefrom1.size(); k++) {
                            String parastritem = valuefrom1.getString(k);
                            if (k != 0) {
                                paravaluefrom.append(",");
                            }
                            paravaluefrom.append(parastritem);
                        }
                        argupara.setValue(paravaluefrom.toString());
                        System.out.println(argupara.getValue());
                    }


                    argumparalist.add(argupara);
//                    argumentsparam.add(paremname);
//                    argumentsvalue.add(paramvalue);
                }

                //20210913    artifacts    -------input中也包含
                List<Artifact> artifactlist = new LinkedList<Artifact>();
                JSONArray argumentsartifacts = rectdata.getJSONArray("argumentsartifacts");
                for (int j = 0; j < argumentsartifacts.size(); j++) {
                    //{{tasks.generate-artifact(tasks   步骤名).outputs.artifacts.hello-art}}
                    String arguartiname = argumentsartifacts.getJSONObject(j).getString("paraname");
                    Artifact arguartifact = new Artifact();
                    arguartifact.setName(arguartiname);

                    //20211127 判断是自输入文件还是 引用前面某一个步骤  -- 待完成
                    //1.需对获取到的值进行判断，是否为引用上一个   {{tasks.generate-artifact(tasks   步骤名).outputs.artifacts.hello-art}}
                    if (argumentsartifacts.getJSONObject(j).getString("valuefrom").length() != 0) {
                        String arguartifrom = argumentsartifacts.getJSONObject(j).getString("valuefrom");
                        arguartifact.setFrom(arguartifrom);
                    }
                    //2.判断,判断前端是否是从  外部输入
//                    String fileurls = argumentsartifacts.getJSONObject(j).getString("fileurls");//数组？
                    JSONArray fileurls = argumentsartifacts.getJSONObject(j).getJSONArray("fileurls");
                    if (fileurls.size() >= 1) {
                        String fileurl;
                        fileurl = fileurls.get(0).toString();
                        System.out.println("fileurl" + fileurl);
                        HTTPArtifact http = new HTTPArtifact();
                        http.setUrl(fileurl);
                        arguartifact.setHttp(http);
                    }

                    //3.判断是否从 输入节点引入
                    JSONArray inputnodefilevalue = argumentsartifacts.getJSONObject(j).getJSONArray("inputnodefilevalue");
                    if (inputnodefilevalue.size() >= 1) {
                        String inputfileurl = inputnodefilevalue.get(0).toString();
                        System.out.println("inputfileurl" + inputfileurl);
                        HTTPArtifact http = new HTTPArtifact();
                        http.setUrl(inputfileurl);
                        arguartifact.setHttp(http);
                    }


                    artifactlist.add(arguartifact);
                }

                Arguments arguments = new Arguments();
                arguments.setParameters(argumparalist);
                arguments.setArtifacts(artifactlist);

                //通过Rect型节点数据  创建template，将template作为DAGTask添加到List<DAGTask>中，
                Template template = new Template();
                template.setName(templateName);
                template.setInputs(inputs);
                template.setOutputs(outputs);
                //设置template类型为Container
                V1Container containertemp = new V1Container();
                containertemp.setImage(templateImage);
                containertemp.setCommand(command);   //List<String> command
                containertemp.args(args);  //List<String> args
                containertemp.setEnv(envlist);   //20211208
                // 设置代码拉取规则
                containertemp.setImagePullPolicy("IfNotPresent");

                template.setContainer(containertemp);
                //添加至workflowTemplate的List<Template> templateslist中
                templateslist.add(template);
                //添加至DAG中
                DAGTask dagTask = new DAGTask();
                //与当前template name  保持一致
                dagTask.setName(template.getName());  //此处可变-------nodeName20211124

                dagTask.setArguments(arguments);
                dagTask.setTemplate(template.getName());

                //记录对应节点  id  以及添加至DAG中的dagtask中的Name
                idtempname.put(rectid, dagTask.getName());

                //记录对应节点id以及twmplate name之间的对应关系
                idTemplateNameMap.put(rectid, template.getName());

//                for(int k=0;k<edgearray.size();k++){
//                    String targetID = edgearray.getJSONObject(i).getString("targetID");
//                    if(targetID.equals(rectid)){
//
//                    }
//                }
//                dagTask.setDependencies();//依赖于DAGTask 的name
//                //依赖关系需由边决定   如果此处已经添加至taskslist中， 后续根据边添加其依赖如果不起作用，则需先遍历边确定依赖关系，然后在此处寻找遍历边的关系结果，直接填充


                taskslist.add(dagTask);


            }
//            //判断若为edge,则表示边,存储节点前后依赖关系,为target节点(有ID)对应的template，在DAG中为其相应的DAGTask添加dependence，为source节点(通过ID查询)对应的templateName
//            if(cellsarray.getJSONObject(i).getString("shape").equals("edge")){
//                //获取源节点ID
//                JSONObject edgesource = cellsarray.getJSONObject(i).getJSONObject("source");
//                String sourceID = edgesource.getString("cell");
//                //获取目标节点ID
//                JSONObject edgetarget = cellsarray.getJSONObject(i).getJSONObject("target");
//                String targetID = edgetarget.getString("cell");
//                System.out.println("edge:"+cellsarray.getJSONObject(i).getString("id")+" sourceId :"+sourceID+" targetID: "+targetID);
//
//            }

        }

        //
        //创建DAGTasks成功后，遍历所有边，为目标节点对应的DAGTask 添加 源节点对应的DAGTask  依赖
        for (int i = 0; i < cellsarray.size(); i++) {
            //判断若为edge,则表示边,存储节点前后依赖关系,为target节点(有ID)对应的template，在DAG中为其相应的DAGTask添加dependence，为source节点(通过ID查询)对应的templateName
            if (cellsarray.getJSONObject(i).getString("shape").equals("edge")) {
                //获取源节点ID
                JSONObject edgesource = cellsarray.getJSONObject(i).getJSONObject("source");
                String sourceID = edgesource.getString("cell");

                //获取目标节点ID
                JSONObject edgetarget = cellsarray.getJSONObject(i).getJSONObject("target");
                String targetID = edgetarget.getString("cell");

                //根据目标节点ID获取目标节点对应的DAGTask  name
                String targetname = idtempname.get(targetID);
                //根据源节点ID获取源节点对应的DAGTask  name
                String sourcename = idtempname.get(sourceID);

                //20210730--------增加条件分支后 ，需判断根据源节点id获取到的DAGTask  name是否为空；若为空，则表示其源节点为条件节点，则不添加依赖关系，应添加  条件when
                //若条件节点连接的还是条件节点，则该条件节点连接的目标节点id  -------则还是条件分支引出来的边，已做处理
                //若普通节点引出边到条件节点，则遍历taskslist不会找到对应的dagtask  name
                // ---------------现在需清楚怎样判断条件节点的哪一条边条件为真，哪一条边条件为假
                if (sourcename != null) {
                    for (DAGTask dagTask : taskslist) {
                        if (dagTask.getName().equals(targetname)) {
                            dagTask.addDependenciesItem(sourcename);
                            //是否需要break?
                        }
                    }
                }

            }
        }

        //20210730 zhang
        //创建DAGTasks成功后，遍历所有条件节点，为目标节点对应的DAGTask 添加 目标节点对应的DAGTask   when条件
        for (int i = 0; i < cellsarray.size(); i++) {
            //条件节点暂时类型为polygon
            if (cellsarray.getJSONObject(i).getString("shape").equals("polygon")) {
                JSONObject conditiondata = cellsarray.getJSONObject(i).getJSONObject("data");
                //获取条件
                String inputcondition = conditiondata.getString("inputcondition");
                //获取条件为真的边连接的节点的id
                String truetargetid = conditiondata.getString("truetargetid");
                //根据目标节点ID获取目标节点对应的DAGTask  name
                String truetargetname = idtempname.get(truetargetid);
                System.out.println("条件：" + inputcondition);
                System.out.println("条件为真：" + truetargetid + " --DAGTask name:  " + truetargetname);

                //获取条件为假的边连接的节点的id
                String falsetargetid = conditiondata.getString("falsetargetid");
                //根据目标节点ID获取目标节点对应的DAGTask  name
                String falsetargetname = idtempname.get(falsetargetid);
                System.out.println("条件为假：" + falsetargetid + " --DAGTask name:  " + falsetargetname);


                //若条件节点连接的还是条件节点，则该条件节点连接的目标节点id  并没有对应的DAGTask,查询不到其对应的targetname, 因此进行下列程序判断的时候并不会添加 条件
                for (DAGTask dagTask : taskslist) {
                    //考虑如果多个条件节点连接，先判断是否      -------前端判断？
                    //如果有多个条件节点指向同一个节点，则表示可能该  节点对应的when已有值，不能直接覆盖，需进行  与 添加

                    //真
                    if (dagTask.getName().equals(truetargetname)) {
                        String dagTaskWhen = dagTask.getWhen();
                        System.out.println("为真 条件");
                        if (dagTaskWhen != null) {
                            //添加条件语句
                            dagTask.setWhen(dagTaskWhen + "&&(" + inputcondition + ")");
                            System.out.println("为真 条件:" + dagTask.getWhen());
                            //是否需要break?
                        } else {
                            dagTask.setWhen(inputcondition);
                            System.out.println("为真 条件:" + dagTask.getWhen());
                        }

                    }
                    //假
                    if (dagTask.getName().equals(falsetargetname)) {
                        //添加条件语句   需对原语句取反   添加！还是？？？？？？？？？？？？？？？？？？
                        //参数为String
                        String invcondition = "!(" + inputcondition + ")";

                        String dagTaskWhen = dagTask.getWhen();
                        if (dagTaskWhen != null) {
                            //添加条件语句
                            dagTask.setWhen(dagTaskWhen + "&&(" + invcondition + ")");
                            //是否需要break?
                            System.out.println("为假 条件:" + dagTask.getWhen());
                        } else {
                            dagTask.setWhen(invcondition);
                            System.out.println("为假 条件:" + dagTask.getWhen());
                        }
                    }
                }
            }
        }

        dagTemplate.setTasks(taskslist);
        dagtemp.setDag(dagTemplate);
        templateslist.add(dagtemp);  //添加Dag   template

        workflowTemplateSpec.setTemplates(templateslist);
        workflowTemplate1.setSpec(workflowTemplateSpec);
        body.setTemplate(workflowTemplate1);
        WorkflowTemplate resultWorkflowtemplate = null;
        System.out.println("body" + body.toString());
        try {
            //更改为argo utils
//            resultWorkflowtemplate = apiInstance.workflowTemplateServiceCreateWorkflowTemplate(namespace, body);
            resultWorkflowtemplate = ArgoUtils.createWorkflowTemplate(namespace, body);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        //获取创建成功的WorkflowTemplate  Name
        System.out.println(resultWorkflowtemplate.getMetadata().getName());
        String workflowTempname = resultWorkflowtemplate.getMetadata().getName();


        //完成workflowTemplate创建，以此workflowtemplate为模板，提交workflow
//        WorkflowServiceApi workflowServiceApi = new WorkflowServiceApi(defaultClient);

//        String namespace = "default"; // String |                //对应命名空间下的workflowTemplate
        WorkflowSubmitRequest workflowbody = new WorkflowSubmitRequest();
        workflowbody.setNamespace(namespace);       //暂时无用

        workflowbody.setResourceKind("WorkflowTemplate");
        workflowbody.setResourceName(workflowTempname);
        SubmitOpts submitOpts = new SubmitOpts();
        submitOpts.setGenerateName("algorithm-visual-");  //GenerateName overrides metadata.generateName
//        submitOpts.setServiceAccount("report-api");
        submitOpts.setServiceAccount("default");
        workflowbody.setSubmitOptions(submitOpts);
        Workflow resultWorkflow = null;
        try {
            //更改为argo utils
//            resultWorkflow = workflowServiceApi.workflowServiceSubmitWorkflow(namespace, workflowbody);
            resultWorkflow = ArgoUtils.submitWorkflow(namespace, workflowbody);
        } catch (ApiException e) {
            e.printStackTrace();
        }

//        //20211109   保存至数据库
//        System.out.println(resultWorkflow.getMetadata().getName());
//        VisiWorkflowEntity visiwe = new VisiWorkflowEntity();
//        Long userId = ShiroUtils.getUserEntity().getUserId();
//        visiwe.setUserId(userId);
//        visiwe.setGraphJson(jsonObject.toJSONString());
//
////        return "redirect:/save?visiWorkflow=visiwe";

        String resultWorkflowname = resultWorkflow.getMetadata().getName();//提交后的工作流名称
        JSONArray idpodlogs = new JSONArray();//保存 各个节点  podname templatename     podlog 的内容
        String workflowcontent = "";//整个工作流的日志
//        try {
//
//            String logOptionsContainer ="main";  //main  init wait
//            Boolean logOptionsFollow = true;
//            Boolean logOptionsPrevious = false;
//            //获取该工作流的日志
//            StreamResultOfLogEntry workflowResultOfLogEntry = workflowServiceApi.workflowServiceWorkflowLogs(namespace, resultWorkflowname, null, logOptionsContainer, logOptionsFollow, logOptionsPrevious, null, null, null, null, null, null, null);
//            workflowcontent = workflowResultOfLogEntry.getResult().getContent();
//
//            //根据提交后的工作流名称获取该工作流完整信息
//            Workflow successworkflow = workflowServiceApi.workflowServiceGetWorkflow(namespace, resultWorkflowname, null, null);
//            Map<String, NodeStatus> nodeStatusMap = successworkflow.getStatus().getNodes();
////            JSONArray idpodlogs = new JSONArray();//保存 各个节点  podname templatename     podlog 的内容
//            for(Map.Entry<String,NodeStatus> entry : nodeStatusMap.entrySet()){
//                //
//                if(entry.getValue().getType().equals("Pod")){
//                    System.out.println("key: "+entry.getKey());
//                    System.out.println("podname: "+entry.getValue().getId());
//                    System.out.println("templateName: "+entry.getValue().getTemplateName());
//                    System.out.println("step/dag_name: "+entry.getValue().getDisplayName());
//                    System.out.println("step: "+entry.getValue().getType());
////                    System.out.println(++i);
//
//                    String key = entry.getKey();
////                    NodeStatus nodeStatus = entry.getValue();
//                    String podname = entry.getValue().getId();
//                    String templateName = entry.getValue().getTemplateName();
//                    String displayName = entry.getValue().getDisplayName();
////                    String type = entry.getValue().getType();
//
//
//                    //获取工作流相应pod的日志
//                    StreamResultOfLogEntry podResultOfLogEntry = workflowServiceApi.workflowServiceWorkflowLogs(namespace, resultWorkflowname, podname, logOptionsContainer, logOptionsFollow, logOptionsPrevious, null, null, null, null, null, null, null);
//                    String podcontent = podResultOfLogEntry.getResult().getContent();//获取到的日志
////                    workflowServiceApi.workflowServicePodLogs();
//                    JSONObject idpodlog = new JSONObject();
//                    for(Map.Entry<String,String> idtemplateentry : idTemplateNameMap.entrySet()){
//                        if(idtemplateentry.getValue().equals(templateName)){
//                            //查找 节点id 与templateName 映射对应关系
//                            idpodlog.put("workflowName",resultWorkflowname);
//                            idpodlog.put("nodeid",idtemplateentry.getKey());
//                            idpodlog.put("podname",podname);
//                            idpodlog.put("templateName",templateName);
//                            idpodlog.put("podlog",podcontent);
//
//
//                            idpodlogs.add(idpodlog);
//
//                            break;
//                        }
//                    }
//                }
//
//            }
//        } catch (ApiException e) {
//            e.printStackTrace();
//        }
        //可以先只返回 关系，总的工作流的日志   ；  后续再重新获取对应pod的日志
        //返回当前获取到的日志信息，提交给前端。 前端获取到节点id和podnamde的对应关系，然后在分别获取对应pod 的日志


        //保存 工作流 至数据库
        VisiWorkflowEntity visiWorkflow = new VisiWorkflowEntity();
        visiWorkflow.setUserId(ShiroUtils.getUserEntity().getUserId());
        visiWorkflow.setGraphJson(jsonObject.toJSONString());
        visiWorkflow.setExperimentName(experimentName);
        visiWorkflow.setWorkflowtempName(workflowTempname);
        visiWorkflow.setWorkflowName(resultWorkflowname);
        if(addorupdate){
            //修改
            visiWorkflow.setWorkflowId(workflowId);
            visiWorkflowService.updateById(visiWorkflow);
        }else{
            boolean save = visiWorkflowService.save(visiWorkflow);
//            System.out.println("新增的主键"+visiWorkflow.getWorkflowId());
            workflowId = visiWorkflow.getWorkflowId();
        }


//        //保存 节点id 与 templatename 对应关系
//        VisiNodeidtemplateMapService visiNodeidtemplateMapService = null;
//
//        for(Map.Entry<String,String> idtemplateentry : idTemplateNameMap.entrySet()){
//            VisiNodeidtemplateMapEntity visiNodeidtemplateMap = new VisiNodeidtemplateMapEntity();
//            visiNodeidtemplateMap.setUserId(ShiroUtils.getUserEntity().getUserId());
//            visiNodeidtemplateMap.setWorkflowId(ShiroUtils.getUserEntity().getUserId());//待更改
//            visiNodeidtemplateMap.setWorkflowtempName(workflowTempname);
//            visiNodeidtemplateMap.setWorkflowName(resultWorkflowname);
//            visiNodeidtemplateMap.setGraphnodeid(idtemplateentry.getKey());
//            visiNodeidtemplateMap.setTemplatename(idtemplateentry.getValue());
//            visiNodeidtemplateMap.setPodname("");
//            visiNodeidtemplateMapService.save(visiNodeidtemplateMap);
//        }


        return R.ok().put("workflowName", resultWorkflowname).put("idTemplateNameMap", idTemplateNameMap).put("workflowId", workflowId);
//                put("workflowContent",workflowcontent).put("podlogs",idpodlogs);


    }


//    /**
//     * 根据workflow名称，获取workflown内容，获取 pod 日志
//     */
//
//    //应用JSONObject接收数据
//    @RequestMapping("/getpodlog")
//    public R Getpodlog(@RequestParam Map<String, Object> params){
//        Object workflowName = params.get("workflowName");//工作流名称
////        Object idTemplateNameMap = params.get("idTemplateNameMap");
//        Map<String,String> idTemplateNameMap = (Map<String, String>) params.get("idTemplateNameMap");//前端节点id 及templatename对应关系
//        System.out.println("workflowname + idTemplateNameMap");
//        System.out.println(workflowName);
//        System.out.println(idTemplateNameMap);
//
//        JSONArray idpodlogs = new JSONArray();//保存 各个节点  podname templatename     podlog 的内容
//        String workflowcontent="";//整个工作流的日志
//
//        ApiClient defaultClient = Configuration.getDefaultApiClient();
////            defaultClient.setBasePath("http://192.168.222.100:32639");
//        defaultClient.setBasePath("https://150.158.138.99:31547");
//        defaultClient.setVerifyingSsl(false);
//        JSON json = new JSON().setLenientOnJson(true);
//        defaultClient.setJSON(json);
//
//        WorkflowServiceApi apiInstance = new WorkflowServiceApi(defaultClient);
////        String namespace = "default"; // String |                //对应命名空间下的workflowTemplate
//        String namespace = "argo"; // String |                //对应命名空间下的workflowTemplate
//        String name = workflowName.toString();
//        String logOptionsContainer = "main";
//        Boolean logOptionsFollow = true;
//        Boolean logOptionsPrevious = false;
////            String podname = URLEncoder.encode("artifact-passing-shdv4-213122783", "utf-8");
//        String podname = "artifact-passing-shdv4-213122783";
////            Integer logOptionsSinceTimeNanos = 56; // Integer | Non-negative fractions of a second at nanosecond resolution. Negative second values with fractions must still have non-negative nanos values that count forward in time. Must be from 0 to 999,999,999 inclusive. This field may be limited in precision depending on context.
//        Boolean logOptionsTimestamps = true;
//        String logOptionsTailLines = "11"; // String | If set, the number of lines from the end of the logs to show. If not specified, logs are shown from the creation of the container or sinceSeconds or sinceTime +optional.
//        String logOptionsLimitBytes = "60000";
//        Boolean logOptionsInsecureSkipTLSVerifyBackend = true;
//
////            StreamResultOfIoArgoprojWorkflowV1alpha1LogEntry streamResultOfIoArgoprojWorkflowV1alpha1LogEntry = apiInstance.workflowServicePodLogs(namespace,name,podname,logOptionsContainer,logOptionsFollow,null,null,null,null,null,null,null,null,null);
////            System.out.println(streamResultOfIoArgoprojWorkflowV1alpha1LogEntry);
//
////            StreamResultOfLogEntry streamResultOfLogEntry = apiInstance.workflowServiceWorkflowLogs(namespace, name,null,logOptionsContainer,logOptionsFollow,null,"2021-10-13T07:01:55.948Z",null,null,null,null,null,null);
////            StreamResultOfLogEntry streamResultOfLogEntry = apiInstance.workflowServiceWorkflowLogs(namespace, name,null,logOptionsContainer,logOptionsFollow,null,null,null,null,null,null,null,null);
//        StreamResultOfLogEntry streamResultOfLogEntry = apiInstance.workflowServiceWorkflowLogs(namespace, name,null,logOptionsContainer,logOptionsFollow,logOptionsPrevious,null,null,null,logOptionsTimestamps,logOptionsTailLines,logOptionsLimitBytes,logOptionsInsecureSkipTLSVerifyBackend);
////        System.out.println(streamResultOfLogEntry);
//
//        try {
//            //获取该工作流的日志
//            StreamResultOfLogEntry workflowResultOfLogEntry = workflowServiceApi.workflowServiceWorkflowLogs(namespace, name, null, logOptionsContainer, logOptionsFollow, logOptionsPrevious, null, null, null, null, null, null, null);
//            workflowcontent = workflowResultOfLogEntry.getResult().getContent();
//
//            //根据提交后的工作流名称获取该工作流完整信息
//            Workflow successworkflow = workflowServiceApi.workflowServiceGetWorkflow(namespace, resultWorkflowname, null, null);
//            Map<String, NodeStatus> nodeStatusMap = successworkflow.getStatus().getNodes();
////            JSONArray idpodlogs = new JSONArray();//保存 各个节点  podname templatename     podlog 的内容
//            for (Map.Entry<String, NodeStatus> entry : nodeStatusMap.entrySet()) {
////                //
////                if (entry.getValue().getType().equals("Pod")) {
////                    System.out.println("key: " + entry.getKey());
////                    System.out.println("podname: " + entry.getValue().getId());
////                    System.out.println("templateName: " + entry.getValue().getTemplateName());
////                    System.out.println("step/dag_name: " + entry.getValue().getDisplayName());
////                    System.out.println("step: " + entry.getValue().getType());
//////                    System.out.println(++i);
////
////                    String key = entry.getKey();
//////                    NodeStatus nodeStatus = entry.getValue();
////                    String podname = entry.getValue().getId();
////                    String templateName = entry.getValue().getTemplateName();
////                    String displayName = entry.getValue().getDisplayName();
//////                    String type = entry.getValue().getType();
////
////
////                    //获取工作流相应pod的日志
////                    StreamResultOfLogEntry podResultOfLogEntry = workflowServiceApi.workflowServiceWorkflowLogs(namespace, resultWorkflowname, podname, logOptionsContainer, logOptionsFollow, logOptionsPrevious, null, null, null, null, null, null, null);
////                    String podcontent = podResultOfLogEntry.getResult().getContent();//获取到的日志
//////                    workflowServiceApi.workflowServicePodLogs();
////                    JSONObject idpodlog = new JSONObject();
////                    for (Map.Entry<String, String> idtemplateentry : idTemplateNameMap.entrySet()) {
////                        if (idtemplateentry.getValue().equals(templateName)) {
////                            //查找 节点id 与templateName 映射对应关系
////                            idpodlog.put("workflowName", resultWorkflowname);
////                            idpodlog.put("nodeid", idtemplateentry.getKey());
////                            idpodlog.put("podname", podname);
////                            idpodlog.put("templateName", templateName);
////                            idpodlog.put("podlog", podcontent);
////
////
////                            idpodlogs.add(idpodlog);
////
////                            break;
////                        }
////                    }
////                }
//
//            }
//        } catch (ApiException e) {
//            e.printStackTrace();
//        }
//        return R.ok();
////                .put("workflowName",resultWorkflowname).put("idTemplateNameMap",idTemplateNameMap).put("workflowContent",workflowcontent).put("podlogs",idpodlogs);
//    }


//    //应用Map接收数据
//    @RequestMapping("/submit")
//    public R Submit(@RequestBody Map jsonObject){
////        visiWorkflowService.save(visiWorkflow);
//
//        //获取前端流程数据
////        System.out.println(jsonObject.toJSONString());
//        System.out.println(jsonObject);
//        System.out.println(jsonObject.get("cells"));
////        Object cells = jsonObject.get("cells");
////        System.out.println("cells"+cells);
//
//        return R.ok();
//    }

    /**
     * 根据workflow名称，获取workflown日志
     */

    //应用JSONObject接收数据

    /**
     * 当前使用
     * 获取workflow日志
     *
     * @param params workflow名称及节点映射关系
     * @return workflow日志信息
     * 20220428
     */
    @RequestMapping("/getworkflowlog2")
    public R Getworkflowlog2(@RequestParam Map<String, Object> params) throws Exception {
        Object workflowName = params.get("workflowName");//工作流名称
        String namespace = "argo"; // String |                //对应命名空间下的workflowTemplate
        String name = workflowName.toString();
//        String workflowcontent="";//整个工作流的日志
        Map<String, String> workflowcontent = new HashMap<String, String>();//日志
        String mainlog = ArgoUtils.getWorkflowlog(namespace, name, "main");
        String initlog = ArgoUtils.getWorkflowlog(namespace, name, "init");
        String waitlog = ArgoUtils.getWorkflowlog(namespace, name, "wait");

        workflowcontent.put("main", mainlog);
        workflowcontent.put("init", initlog);
        workflowcontent.put("wait", waitlog);
        System.out.println(workflowcontent);
        String workflowStatus = ArgoUtils.getWorkflowStatus(namespace, name);

        return R.ok().put("workflowContent", workflowcontent).put("workflowStatus",workflowStatus);
    }

    /**
     * 根据workflow名称，获取workflown日志
     */

    //应用JSONObject接收数据

    /**
     * 获取workflow日志
     *
     * @param params workflow名称及节点映射关系
     * @return workflow日志信息
     */
    @RequestMapping("/getworkflowlog")
    public R Getworkflowlog(@RequestParam Map<String, Object> params) throws IOException, InterruptedException {
        Object workflowName = params.get("workflowName");//工作流名称
        System.out.println("workflowname + idTemplateNameMap");
        System.out.println(workflowName);
//        String workflowcontent="";//整个工作流的日志
        Map<String, String> workflowcontent = new HashMap<String, String>();//日志
        StringBuilder sbmain = new StringBuilder();
        StringBuilder sbinit = new StringBuilder();
        StringBuilder sbwait = new StringBuilder();

        String namespace = "argo"; // String |                //对应命名空间下的workflowTemplate
        String name = workflowName.toString();
////        String logOptionsContainer = "main";
//        String logOptionsContainermain = "main";
//        String logOptionsContainerinit = "init";
//        String logOptionsContainerwait = "wait";
        //根据提交后的工作流名称获取该工作流完整信息
        Workflow successworkflow = null;
//        do{
        try {
            //更改为应用ArgoUtils
//            successworkflow = apiInstance.workflowServiceGetWorkflow(namespace, workflowName.toString(), null, null);
            successworkflow = ArgoUtils.getWorkflow(namespace, workflowName.toString());

            //创建一个api对象
            CoreV1Api api = new CoreV1Api();

            Map<String, NodeStatus> nodeStatusMap = successworkflow.getStatus().getNodes();
            for (Map.Entry<String, NodeStatus> entry : nodeStatusMap.entrySet()) {
                //
                if (entry.getValue().getType().equals("Pod")) {
//                    String templateName = entry.getValue().getTemplateName();
//                    String displayName = entry.getValue().getDisplayName();   //dag  taskname唯一
                    String podname = entry.getValue().getId();
                    System.out.println("podname");
                    System.out.println(podname);
                    String podphase = entry.getValue().getPhase();
                    if (podphase.equals("Pending")) {
//                            sbmain.append("pod初始化中");
//                            sbmain.append("\n");
                    } else {
                        List<V1Container> podContainers = KubernetesUtils.getPodContainers(namespace, podname);
                        if (podContainers != null) {
                            for (V1Container container : podContainers) {
//                container.getName();
//                System.out.println(container.getName());
                                InputStream inputStream1 = KubernetesUtils.getPodLog(namespace, podname, container.getName());
                                String podcontentmain1 = new BufferedReader(new InputStreamReader(inputStream1)).lines().collect(Collectors.joining(System.lineSeparator()));
                                if (container.getName().equals("main")) {
                                    System.out.println("main: " + podcontentmain1);
                                    sbmain.append(podcontentmain1);
                                    sbmain.append("\n");
                                } else if (container.getName().equals("init")) {
                                    System.out.println("init: " + podcontentmain1);
                                    sbinit.append(podcontentmain1);
                                    sbinit.append("\n");
                                } else if (container.getName().equals("wait")) {
                                    System.out.println("wait: " + podcontentmain1);
                                    sbwait.append(podcontentmain1);
                                    sbwait.append("\n");
                                }
                            }
                        } else {
                            System.out.println("当前pod中镜像为空");
                        }

                    }

//
//                    //获取工作流相应pod的日志
////                    InputStream inputStreammain = new PodLogs(kubeClient).streamNamespacedPodLog(namespace, podname, logOptionsContainermain);
//                    InputStream inputStreammain = KubernetesUtils.getPodLog(namespace, podname, logOptionsContainermain);
//                    String podcontentmain = new BufferedReader(new InputStreamReader(inputStreammain)).lines().collect(Collectors.joining(System.lineSeparator()));
//                    sbmain.append(podcontentmain);
//                    sbmain.append("/n");
//
//                    //                    InputStream inputStreamwait = new PodLogs(kubeClient).streamNamespacedPodLog(namespace, podname, logOptionsContainerwait);
//                    InputStream inputStreamwait = KubernetesUtils.getPodLog(namespace, podname, logOptionsContainerwait);
//                    String podcontentwait = new BufferedReader(new InputStreamReader(inputStreamwait)).lines().collect(Collectors.joining(System.lineSeparator()));
//                    sbwait.append(podcontentwait);
//                    sbwait.append("/n");
//
////                    InputStream inputStreaminit = new PodLogs(kubeClient).streamNamespacedPodLog(namespace, podname, logOptionsContainerinit);
//                    InputStream inputStreaminit = KubernetesUtils.getPodLog(namespace, podname, logOptionsContainerinit);
//                    String podcontentinit = new BufferedReader(new InputStreamReader(inputStreaminit)).lines().collect(Collectors.joining(System.lineSeparator()));
//                    sbinit.append(podcontentinit);
//                    sbinit.append("/n");


                }

            }

        } catch (ApiException | FileNotFoundException e) {
            e.printStackTrace();
        } catch (io.kubernetes.client.openapi.ApiException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        workflowcontent.put("main", sbmain.toString());
        workflowcontent.put("init", sbinit.toString());
        workflowcontent.put("wait", sbwait.toString());
        System.out.println(workflowcontent);
        String paramjson = JSONObject.toJSONString(workflowcontent);
//        MyWebSocket.sendMessage(paramjson);
//            Thread.sleep(1000*3);   // 休眠3秒
//        }while(successworkflow.getStatus().getPhase()!="Succeeded"&&successworkflow.getStatus().getPhase()!="Error"&&successworkflow.getStatus().getPhase()!="Failed");
//        MyWebSocket.sendMessage("日志获取结束");
        return R.ok().put("workflowContent", workflowcontent);
//                .put("workflowName",resultWorkflowname).put("idTemplateNameMap",idTemplateNameMap).put("workflowContent",workflowcontent).put("podlogs",idpodlogs);
    }


    /**
     * 根据workflow名称，获取workflown内容，获取 pod 日志
     */

    //应用JSONObject接收数据

    /**
     * 当前应用
     * 根据workflow名称，获取workflown内容，获取 pod 日志
     *
     * @param params workflow名称及节点映射关系
     * @return pod日志信息
     */
    @RequestMapping("/getpodlog2")
    public R Getpodlog2(@RequestParam Map<String, Object> params) throws IOException, InterruptedException {
        Object workflowName = params.get("workflowName");//工作流名称
//        Object idTemplateNameMap = params.get("idTemplateNameMap");
//        Map<String,String> idTemplateNameMap = (Map<String, String>) params.get("idTemplateNameMap");//前端节点id 及templatename对应关系
        JSONObject idTemplateNameMap = com.alibaba.fastjson.JSON.parseObject(params.get("idTemplateNameMap").toString());
        Object nodeId = params.get("nodeId");
        System.out.println("workflowname + idTemplateNameMap+nodeId");
        System.out.println(workflowName);
        System.out.println(idTemplateNameMap);
        System.out.println(nodeId);
        String templateName = "";//节点名称
        templateName = idTemplateNameMap.getString(nodeId.toString());

        JSONArray idpodlogs = new JSONArray();//保存 各个节点  podname templatename     podlog 的内容
        Map<String, String> podcontent = new HashMap<String, String>();//单个节点日志日志
        podcontent.put("main", " ");
        podcontent.put("wait", " ");
        podcontent.put("init", " ");

        String namespace = "argo"; // String |                //对应命名空间下的workflowTemplate
        String name = workflowName.toString();


        String podname = "";

        //根据提交后的工作流名称获取该工作流完整信息
        Workflow successworkflow = null;
        String podphase = "";
//        do{
        try {
//            successworkflow = apiInstance.workflowServiceGetWorkflow(namespace, workflowName.toString(), null, null);
            successworkflow = ArgoUtils.getWorkflow(namespace, workflowName.toString());
            Map<String, NodeStatus> nodeStatusMap = successworkflow.getStatus().getNodes();
            for (Map.Entry<String, NodeStatus> entry : nodeStatusMap.entrySet()) {
                //
                if (entry.getValue().getType().equals("Pod")) {
//                    String templateName = entry.getValue().getTemplateName();
//                    String displayName = entry.getValue().getDisplayName();   //dag  taskname唯一

                    if (entry.getValue().getDisplayName().equals(templateName)) {
                        podname = entry.getValue().getId();
                        System.out.println("podname");
                        System.out.println(podname);
                        podphase = entry.getValue().getPhase();
                        String main = ArgoUtils.getpodlog(namespace, workflowName.toString(), "main", podname);
                        String init = ArgoUtils.getpodlog(namespace, workflowName.toString(), "init", podname);
                        String wait = ArgoUtils.getpodlog(namespace, workflowName.toString(), "wait", podname);
                        podcontent.put("main",main);
                        podcontent.put("init",init);
                        podcontent.put("wait",wait);
                        break;

                    }
                }
            }


        } catch (ApiException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.ok().put("podname", podname).put("podcontent", podcontent).put("podphase",podphase);
    }
    /**
     * 根据workflow名称，获取workflown内容，获取 pod 日志
     */

    //应用JSONObject接收数据

    /**
     * 根据workflow名称，获取workflown内容，获取 pod 日志
     *
     * @param params workflow名称及节点映射关系
     * @return pod日志信息
     */
    @RequestMapping("/getpodlog")
    public R Getpodlog(@RequestParam Map<String, Object> params) throws IOException, InterruptedException {
        Object workflowName = params.get("workflowName");//工作流名称
//        Object idTemplateNameMap = params.get("idTemplateNameMap");
//        Map<String,String> idTemplateNameMap = (Map<String, String>) params.get("idTemplateNameMap");//前端节点id 及templatename对应关系
        JSONObject idTemplateNameMap = com.alibaba.fastjson.JSON.parseObject(params.get("idTemplateNameMap").toString());
        Object nodeId = params.get("nodeId");
        System.out.println("workflowname + idTemplateNameMap+nodeId");
        System.out.println(workflowName);
        System.out.println(idTemplateNameMap);
        System.out.println(nodeId);
        String templateName = "";//节点名称
        templateName = idTemplateNameMap.getString(nodeId.toString());

        JSONArray idpodlogs = new JSONArray();//保存 各个节点  podname templatename     podlog 的内容
        Map<String, String> podcontent = new HashMap<String, String>();//单个节点日志日志
        podcontent.put("main", " ");
        podcontent.put("wait", " ");
        podcontent.put("init", " ");

        String namespace = "argo"; // String |                //对应命名空间下的workflowTemplate
        String name = workflowName.toString();
//        String logOptionsContainermain = "main";
//        String logOptionsContainerinit = "init";
//        String logOptionsContainerwait = "wait";
//        Boolean logOptionsFollow = true;
//        Boolean logOptionsPrevious = false;

        String podname = "";

        //根据提交后的工作流名称获取该工作流完整信息
        Workflow successworkflow = null;
        String podphase = "";
//        do{
        try {
//            successworkflow = apiInstance.workflowServiceGetWorkflow(namespace, workflowName.toString(), null, null);
            successworkflow = ArgoUtils.getWorkflow(namespace, workflowName.toString());
            Map<String, NodeStatus> nodeStatusMap = successworkflow.getStatus().getNodes();
            for (Map.Entry<String, NodeStatus> entry : nodeStatusMap.entrySet()) {
                //
                if (entry.getValue().getType().equals("Pod")) {
//                    String templateName = entry.getValue().getTemplateName();
//                    String displayName = entry.getValue().getDisplayName();   //dag  taskname唯一

                    if (entry.getValue().getDisplayName().equals(templateName)) {
                        podname = entry.getValue().getId();
                        System.out.println("podname");
                        System.out.println(podname);
                        podphase = entry.getValue().getPhase();
                        switch (podphase) {
                            case "Running":
                                podcontent = KubernetesUtils.getPodLog2(namespace, podname, podcontent);
                                break;
                            case "ContainerCreating":
                                podcontent.put("main", "容器创建中");
                                break;
                            case "Pending":
                                podcontent.put("main", "Pod初始化中");
                            case "Completed":
                                podcontent = KubernetesUtils.getPodLog2(namespace, podname, podcontent);
                                break;
                            default:
                                podcontent = KubernetesUtils.getPodLog2(namespace, podname, podcontent);
                                break;

                        }
//                            podcontent = KubernetesUtils.getPodLog2(namespace, podname, podcontent);
                        break;


//                        //创建一个api对象
//                        CoreV1Api api = new CoreV1Api();
//                        //获取工作流相应pod的日志
////                        InputStream inputStreammain = new PodLogs(client).streamNamespacedPodLog(namespace, podname, logOptionsContainermain);
//                        InputStream inputStreammain = KubernetesUtils.getPodLog(namespace, podname, logOptionsContainermain);
//                        String podcontentmain= new BufferedReader(new InputStreamReader(inputStreammain)).lines().collect(Collectors.joining(System.lineSeparator()));
//                        podcontent.put("main",podcontentmain);
//                        System.out.println("mainpodcontent");
//                        System.out.println(podcontent.get("main"));
//
//                        //                        InputStream inputStreamwait = new PodLogs(client).streamNamespacedPodLog(namespace, podname, logOptionsContainerwait);
//                        InputStream inputStreamwait = KubernetesUtils.getPodLog(namespace, podname, logOptionsContainerwait);
//                        String podcontentwait= new BufferedReader(new InputStreamReader(inputStreamwait)).lines().collect(Collectors.joining(System.lineSeparator()));
//                        podcontent.put("wait",podcontentwait);
//
//
////                        InputStream inputStreaminit = new PodLogs(client).streamNamespacedPodLog(namespace, podname, logOptionsContainerinit);
//                        InputStream inputStreaminit = KubernetesUtils.getPodLog(namespace, podname, logOptionsContainerinit);
//                        String podcontentinit= new BufferedReader(new InputStreamReader(inputStreaminit)).lines().collect(Collectors.joining(System.lineSeparator()));
//                        podcontent.put("init",podcontentinit);
//                        System.out.println("initpodcontent");
//                        System.out.println(podcontent.get("init"));


                    }
                }

            }

        } catch (ApiException | FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }
        String podcontentjson = JSONObject.toJSONString(podcontent);
//        MyWebSocket.sendMessage(podcontentjson);
//            Thread.sleep(1000*3);   // 休眠3秒
//        }while(podphase!="Succeeded"&&podphase!="Completed"&&podphase!="Failed");
//        MyWebSocket.sendMessage("获取节点日志结束");
        return R.ok().put("podname", podname).put("podcontent", podcontent);
//                .put("workflowName",resultWorkflowname).put("idTemplateNameMap",idTemplateNameMap).put("workflowContent",workflowcontent).put("podlogs",idpodlogs);
    }


//    //查询workflow 执行状态-----还没写
//    @RequestMapping("/getworkflowstatus")
//    public R Getworkflowstatus(@RequestParam Map<String, Object> params){
//        return R.ok();
//
//    }
    //查询workflow 执行状态

    /**
     * 查询workflow执行状态
     *
     * @param params workflow名称
     * @return workflow执行状态
     */
    @RequestMapping("/getworkflowstatus")
    public R Getworkflowstatus(@RequestParam Map<String, Object> params) {
        Object workflowName = params.get("workflowName");//工作流名称
        System.out.println("workflowname ");
        System.out.println(workflowName);

        String namespace = "argo";
        Workflow successworkflow;
        String statusPhase = "";
        try {
            successworkflow = ArgoUtils.getWorkflow(namespace, workflowName.toString());
            statusPhase = successworkflow.getStatus().getPhase();
//            System.out.println(statusPhase);
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return R.ok().put("statusPhase", statusPhase);

    }

    /**
     * stop  workflow
     *
     * @param params workflow名称
     * @return workflow执行状态
     *
     */
    @RequestMapping("/stopworkflow")
    public R Stopworkflow(@RequestBody Map<String, Object> params) {
        Object workflowName = params.get("workflowName");//工作流名称
        System.out.println("workflowname ");
        System.out.println(workflowName);

        String namespace = "argo";
        String statusPhase = "";
        try {
            statusPhase = ArgoUtils.stopWorkflow(namespace, workflowName.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        Workflow successworkflow;

        return R.ok().put("statusPhase", statusPhase);

    }

    /**
     * 获取输入csv表头信息
     *
     * @param params workflow名称
     * @return workflow执行状态
     *
     */
    @RequestMapping("/getCSVHeader")
    public R getCSVHeaderInfo(@RequestParam Map<String, Object> params) throws IOException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, ErrorResponseException, XmlParserException, InvalidBucketNameException, InsufficientDataException, InternalException {
        Object filename = params.get("filename");//工作流名称
        Object bucketname = params.get("bucketname");//工作流名称
        System.out.println(bucketname.toString());
        System.out.println(filename.toString());
        InputStream fileInputStream = null;
        if(bucketname.toString().equals("visiarguartifact")){
            fileInputStream = MinIoUtils.getFileInputStream(bucketname.toString(), "argoworkflow" + "/" + filename.toString());

        }else{
            fileInputStream = MinIoUtils.getFileInputStream(bucketname.toString(), filename.toString()+".csv");
        }

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));


        String line = null;
        int index=0;//总行数
        int col = 0;//列
        //表头
        String[] headerinfo = null;
        //前五行数据
        List<String[]> allString = new ArrayList<>();

        //读取每行，直到为空
        while((line=bufferedReader.readLine())!=null){
            index++;
            if(index==1){
                //读取首行
                headerinfo = line.split(",");//CSV格式文件为逗号分隔符文件，这里根据逗号切分
                col = headerinfo.length;
                for (String s : headerinfo) {
                    System.out.println(s);
                }
            }else{
                allString.add(line.split(","));
            }

//            else if(index<=5){ //读取五行
//                allString.add(line.split(","));
//            }

        }

        return R.ok().put("index", index).put("col",col).put("headerinfo",headerinfo).put("allstring",allString);

    }

    /**
     * 根据行列创建新的csv文件
     *
     * @param params workflow名称
     * @return workflow执行状态
     *
     */
    @RequestMapping("/getnewfile")
    public R getnewfile(@RequestParam Map<String, Object> params) throws IOException, InvalidResponseException, InvalidKeyException, NoSuchAlgorithmException, ErrorResponseException, XmlParserException, InvalidBucketNameException, InsufficientDataException, InternalException {
        Object filename = params.get("filename");//文件名称
        Object bucketname = params.get("bucketname");//桶名称
        Object rowminnum = params.get("rowminnum");
        Object rowmaxnum = params.get("rowmaxnum");
        Object colminnum = params.get("colminnum");
        Object colmaxnum = params.get("colmaxnum");

        System.out.println(bucketname.toString());
        System.out.println(filename.toString());
        // 1.读取原数据集
        InputStream fileInputStream = null;
        if(bucketname.toString().equals("visiarguartifact")){
            fileInputStream = MinIoUtils.getFileInputStream(bucketname.toString(), "argoworkflow" + "/" + filename.toString());

        }else{
            fileInputStream = MinIoUtils.getFileInputStream(bucketname.toString(), filename.toString()+".csv");
        }

        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));
        String line = null;
        int index=0;//总行数
        int col = 0;//列
        //表头
        String[] headerinfo = null;
        //前五行数据
        List<String[]> allString = new ArrayList<>();
        //读取每行，直到为空
        while((line=bufferedReader.readLine())!=null){
            index++;
            if(index==1){
                //读取首行
                headerinfo = line.split(",");//CSV格式文件为逗号分隔符文件，这里根据逗号切分
                col = headerinfo.length;
//                for (String s : headerinfo) {
//                    System.out.println(s);
//                }
            }else{
                allString.add(line.split(","));
            }
        }

        //2.根据行列限制设置新文件

        List<String[]> newallString = new ArrayList<>();
        for (int i = Integer.parseInt(rowminnum.toString()); i <= Integer.parseInt(rowmaxnum.toString()); i++) {
            StringBuffer str = new StringBuffer();
            String[] oldstrings = allString.get(i);
            for (int j = Integer.parseInt(colminnum.toString()); j <= Integer.parseInt(colmaxnum.toString()); j++) {
                str.append(oldstrings[j]).append(",");
            }
            String[] split = str.toString().split(",");
            newallString.add(split);
        }

        //2.1 设置输出的文件路径
        //如果该目录下不存在该文件，则文件会被创建到指定目录下。如果该目录有同名文件，那么该文件将被覆盖。
//        File writeFile = new File("src/main/resources/"+"new"+filename.toString());
        File writeFile = new File(datasetLocation+"/new"+filename.toString());

        try{
            //2.2 通过BufferedReader类创建一个使用默认大小输出缓冲区的缓冲字符输出流
            BufferedWriter writeText = new BufferedWriter(new FileWriter(writeFile));
            if(Integer.parseInt(rowminnum.toString())!=0){
                //选中的行不包含表头，添加
                StringBuffer newheaderinfostr = new StringBuffer();
                for (int j = Integer.parseInt(colminnum.toString()); j <= Integer.parseInt(colmaxnum.toString()); j++) {
                    newheaderinfostr.append(headerinfo[j]).append(",");
                }
                String[] newheaderinfo = newheaderinfostr.toString().split(",");

                writeText.write(StringUtils.join(newheaderinfo,","));
                writeText.newLine();
            }
            //2.3 将文档的下一行数据赋值给lineData，并判断是否为空，若不为空则输出
            for(int i=0;i<newallString.size();i++){

                //调用write的方法将字符串写到流中
                writeText.write(StringUtils.join(newallString.get(i),","));
                writeText.newLine();    //换行

            }
            //使用缓冲区的刷新方法将数据刷到目的地中
            writeText.flush();
            //关闭缓冲区，缓冲区没有调用系统底层资源，真正调用底层资源的是FileWriter对象，缓冲区仅仅是一个提高效率的作用
            //因此，此处的close()方法关闭的是被缓存的流对象
            writeText.close();
        }catch (FileNotFoundException e){
            System.out.println("没有找到指定文件");
        }catch (IOException e){
            System.out.println("文件读写出错");
        }

        //上传新文件到minio
//        MinIoUtils.uploadMultipartFile(file, "visiarguartifact", "argoworkflow" + "/" + file.getOriginalFilename());

        InputStream inputStream = new FileInputStream(writeFile);
        MinIoUtils.uploadFileByInputStream(inputStream, (long) inputStream.available(),"visiarguartifact","argoworkflow" + "/" + writeFile.getName());
//        MinIoUtils.uploadLocalFile("visiarguartifact","argoworkflow" + "/" + writeFile.getName(),writeFile.getPath(),null);
        String newfileurl = MinIoUtils.getFileUrl("visiarguartifact", "argoworkflow" + "/" + writeFile.getName());
        //上传成功后删除本地文件
        if(writeFile.exists()) {//判断路径是否存在
//            if(file.isFile()){//boolean isFile():测试此抽象路径名表示的文件是否是一个标准文件。
//                file.delete();
//            }
           writeFile.delete();
        }else {
            System.out.println("该file路径不存在！！");
        }

        return R.ok().put("newfilename", "new"+filename.toString()).put("newfileurl",newfileurl);

    }



}
