package io.renren.modules.sys.controller;

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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import io.argoproj.workflow.ApiClient;
import io.argoproj.workflow.ApiException;
import io.argoproj.workflow.Configuration;
import io.argoproj.workflow.JSON;
import io.argoproj.workflow.apis.WorkflowServiceApi;
import io.argoproj.workflow.models.NodeStatus;
import io.argoproj.workflow.models.Outputs;
import io.argoproj.workflow.models.Parameter;
import io.argoproj.workflow.models.Workflow;
import io.kubernetes.client.PodLogs;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.util.ClientBuilder;
import io.kubernetes.client.util.KubeConfig;
import io.minio.MinioClient;
import io.minio.errors.*;
import io.minio.http.Method;
import io.renren.common.utils.ArgoUtils;
import io.renren.common.utils.MinIoUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
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 io.renren.modules.sys.entity.VisiNodeidtemplateMapEntity;
import io.renren.modules.sys.service.VisiNodeidtemplateMapService;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.R;



/**
 * 管理画布节点与workflow内节点映射关系
 * @author Zhang
 * @version 3.0.0
 * @since JDK1.8
 */
@RestController
@RequestMapping("visi/visinodeidtemplatemap")
public class VisiNodeidtemplateMapController {

    @Autowired
    private VisiNodeidtemplateMapService visiNodeidtemplateMapService;


    /**
     * 列表
     * @param params 页面配置信息
     * @return 映射关系列表
     */
    @RequestMapping("/list")
    @RequiresPermissions("sys:visinodeidtemplatemap:list")
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = visiNodeidtemplateMapService.queryPage(params);

        return R.ok().put("page", page);
    }



    /**
     * 信息
     * @param mapId
     * @return 映射关系
     */
    @RequestMapping("/info/{mapId}")
    @RequiresPermissions("sys:visinodeidtemplatemap:info")
    public R info(@PathVariable("mapId") Long mapId){
		VisiNodeidtemplateMapEntity visiNodeidtemplateMap = visiNodeidtemplateMapService.getById(mapId);

        return R.ok().put("visiNodeidtemplateMap", visiNodeidtemplateMap);
    }

    /**
     * 保存
     * @param visiNodeidtemplateMap 映射关系具体信息
     * @return 提示信息
     */
    @RequestMapping("/save")
    @RequiresPermissions("sys:visinodeidtemplatemap:save")
    public R save(@RequestBody VisiNodeidtemplateMapEntity visiNodeidtemplateMap){
		visiNodeidtemplateMapService.save(visiNodeidtemplateMap);

        return R.ok();
    }

    /**
     * 修改算法节点与workflow内节点映射关系
     * @param visiNodeidtemplateMap
     * @return 提示信息
     */
    @RequestMapping("/update")
    @RequiresPermissions("sys:visinodeidtemplatemap:update")
    public R update(@RequestBody VisiNodeidtemplateMapEntity visiNodeidtemplateMap){
		visiNodeidtemplateMapService.updateById(visiNodeidtemplateMap);

        return R.ok();
    }


    /**
     * 删除
     * @param mapIds
     * @return 提示信息
     */
    @RequestMapping("/delete")
    @RequiresPermissions("sys:visinodeidtemplatemap:delete")
    public R delete(@RequestBody Long[] mapIds){
		visiNodeidtemplateMapService.removeByIds(Arrays.asList(mapIds));

        return R.ok();
    }

    //下载数据集
    /**
     * 下载文件
     * <p>根据workflow名称，节点映射关系，参数名称及来源获取输出文件地址</p>
     * @param params workflow名称，映射关系，参数名称及输出文件来源
     * @return 文件地址及类型
     */
    @RequestMapping("/downloadoutput")
    public R downloadStaticDataset(@RequestParam Map<String, Object> params){
//        //从minio获得数据集的url，直接返回给前端
//        String downloadUrl= MinIoUtils.getFileUrl("dataset",datasetName);

        //通过 workflowname    templateName 和 output artifact 的名称 获取文件下载地址
        Object workflowName = params.get("workflowName");//工作流名称
        Object wftemplatename = params.get("wftemplateName");//节点对应的Template名称
        Object outputartiparaname = params.get("outputartiparaName");//节点对应的output 的artifacts 的参数名称
        Object outputartiparapath = params.get("outputartiparapath");//节点对应的output 的artifacts 的path
        //改为用 path ,通过 /分割字符串 得到参数名称  后通过\\.   分隔得到文件类型
        String[] splitpath = outputartiparapath.toString().split("/");
        String artipath = splitpath[splitpath.length-1];
        //切分出 "\\.",得到文件类型
        String[] splitfiletype = artipath.split("\\.");
        String artifiletype = splitfiletype[splitfiletype.length-1];


        System.out.println("输出节点下载数据集\n"+workflowName.toString());
        System.out.println(wftemplatename.toString());
        System.out.println(outputartiparaname.toString());
        System.out.println(outputartiparapath.toString());

//更改为ArgoUtils
//        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);
//        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 podname = "";
        String outputfileUrl = "";
        //根据提交后的工作流名称获取该工作流完整信息
        Workflow successworkflow = null;
        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(wftemplatename)){
                        podname = entry.getValue().getId();
                        System.out.println("podname");
                        System.out.println(podname);
//                        MinIoUtils argominIoUtils = new MinIoUtils("http://182.92.79.148:32206", "admin", "password");
//                        MinIoUtils argominIoUtils = new MinIoUtils();
//                        MinioClient argominioClient = new MinioClient("http://182.92.79.148:32206", "admin", "password");
                        MinioClient argominioClient = new MinioClient(ArgoUtils.getMinioendpoint(), ArgoUtils.getMinioAccesskey(), ArgoUtils.getMinioSecretkey());

//                        http://182.92.79.148:32206/minio/my-bucket/algorithm-visual-22trh/
                        //获取url
//                        String filename = workflowName.toString()+"/"+podname+"/"+outputartiparaname.toString()+".tgz";
                        String filename = workflowName.toString()+"/"+podname+"/"+artipath;
                        outputfileUrl = argominioClient.getPresignedObjectUrl(Method.GET, "my-bucket", filename, 1000, null);
//                        outputfileUrl = argominIoUtils.getFileUrl("my-bucket", filename);
                        System.out.println("output  "+outputartiparaname.toString()+" fileurl");
                        System.out.println(outputfileUrl);

                    }
                }

            }

        }  catch ( ApiException e) {
            e.printStackTrace();
        } catch (InvalidPortException e) {
            e.printStackTrace();
        } catch (InvalidEndpointException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (InvalidBucketNameException e) {
            e.printStackTrace();
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InvalidExpiresRangeException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


        return R.ok().put("outputfileUrl",outputfileUrl).put("artipath",artipath).put("artifiletype",artifiletype);
    }



    /**
     * 获取参数类型输出值
     * 根据workflow名称，节点映射关系和参数名称获取参数具体输出值
     * @param params workflow名称 ，节点映射关系及输出参数名称
     * @return 参数输出值
     *
     */
    @RequestMapping("/getoutputparavalue")
    public R getOutputparaValue(@RequestParam Map<String, Object> params){

        //通过 workflowname    templateName  获取output参数列表
        Object workflowName = params.get("workflowName");//工作流名称
        Object wftemplatename = params.get("wftemplateName");//节点对应的Template名称

        System.out.println("获取输出参数值\n"+workflowName.toString());
        System.out.println(wftemplatename.toString());

        String namespace = "argo"; // String |                //对应命名空间下的workflowTemplate
        String podname = "";
        JSONArray paravaluearray = new JSONArray();

        //根据提交后的工作流名称获取该工作流完整信息
        Workflow successworkflow = null;
        try {
            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(wftemplatename)){
                        podname = entry.getValue().getId();
                        System.out.println("podname  "+podname);
                        System.out.println(podname);
                        Outputs outputs = entry.getValue().getOutputs();
                        List<Parameter> parameters = outputs.getParameters();
                        for(int i=0;i<parameters.size();i++){
                            String paraname = parameters.get(i).getName();
                            String paravalue = parameters.get(i).getValue();
                            System.out.println(paraname+"  "+paravalue);
                            //保存
                            JSONObject parajson = new JSONObject();
                            parajson.put("name",paraname);
                            parajson.put("value",paravalue);
                            paravaluearray.add(parajson);

                        }



                    }
                }

            }

        }  catch ( ApiException e) {
            e.printStackTrace();
        }


        return R.ok().put("outparavalueJson",paravaluearray);
    }

}
