package io.renren.common.utils;

import com.alibaba.fastjson.JSONObject;
import io.argoproj.workflow.models.NodeStatus;
import io.argoproj.workflow.models.Workflow;
import io.kubernetes.client.PodLogs;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1Container;
import io.kubernetes.client.openapi.models.V1Pod;
import io.kubernetes.client.util.ClientBuilder;
import io.kubernetes.client.util.KubeConfig;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.Configuration;
/**
 * Kubernetes工具，将用于Argo中获取pod日志
 * @author Zhang
 * @version 3.0.0
 * @since JDK1.8
 */
@Slf4j
public class KubernetesUtils {
    private static ApiClient kubeClient;
    private static String kubeConfigPath;
    private static String basepath;


    /**
     * 无参构造函数
     */
    public KubernetesUtils() {
    }

    /**
     * 构造函数
     * @param kubeConfigPath kube配置文件路径
     * @param basepath kubernetes访问地址
     */
    public KubernetesUtils(String kubeConfigPath, String basepath) {
        KubernetesUtils.kubeConfigPath = kubeConfigPath;
        KubernetesUtils.basepath = basepath;

        createKubeClient();
    }


    /**
     * 创建kubenetes ApiClient
     */
    public void createKubeClient(){
        //加载k8s,confg
        //加载群集内配置，包括：
        //    1.服务帐户CA.
        //    2. service-account bearer-token
        //    3.服务帐户命名空间
        //    4.来自预设环境变量的主端点（ip，端口）
//                        defaultClient.setBasePath("https://182.92.79.148:31828");
//                        https://150.158.138.99:6443

        try {
//            System.out.println(kubeConfigPath);
            kubeClient = ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).setBasePath(basepath).setVerifyingSsl(false).build();
            Configuration.setDefaultApiClient(kubeClient);

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



    /**
     * 根据podname 获取pod 日志
     * @param namespace 命名空间
     * @param podname pod名称
     * @param logOptionsContainertype 日志类型
     * @return 日志结果
     * @throws IOException
     * @throws ApiException
     */
    public static InputStream getPodLog(String namespace,String podname,String  logOptionsContainertype) throws IOException, ApiException {
        PodLogs podLogs = new PodLogs(kubeClient);
//        System.out.println(kubeClient.getBasePath()+" "+namespace+" "+podname+" "+logOptionsContainertype);
        InputStream inputStream = podLogs.streamNamespacedPodLog(namespace, podname, logOptionsContainertype);
        return inputStream;
    }

    /**
     * 根据podname 获取pod ，获取pod中容器个数，获取每个容器的日志，返回日志结果
     * @param namespace 命名空间
     * @param podname pod名称
     * @return 日志结果
     * @throws IOException
     * @throws ApiException
     */
    public static Map<String,String> getPodLog2(String namespace, String podname,Map<String,String> podcontent) throws IOException{
        PodLogs podLogs = new PodLogs(kubeClient);
        CoreV1Api apiInstance = new CoreV1Api(kubeClient);
        V1Pod resultpod;
        try {
            resultpod = apiInstance.readNamespacedPod(podname, namespace, "true", true, true);
            List<V1Container> containers1 = resultpod.getSpec().getContainers();
            for(V1Container container:containers1){
//                container.getName();
//                System.out.println(container.getName());
                InputStream inputStream1 = podLogs.streamNamespacedPodLog(namespace, podname, container.getName());
                String podcontentmain1= new BufferedReader(new InputStreamReader(inputStream1)).lines().collect(Collectors.joining(System.lineSeparator()));
                podcontent.put(container.getName(),podcontentmain1);
            }

        } catch (ApiException e) {
            System.out.println();
        }
        return podcontent;

    }

    /**
     * 根据podname 获取pod
     * @param namespace 命名空间
     * @param podname pod名称
     * @return 日志结果
     * @throws IOException
     * @throws ApiException
     */
    public static V1Pod getPod(String namespace, String podname) {
        CoreV1Api apiInstance = new CoreV1Api(kubeClient);
        V1Pod resultpod = null;
        try {
            resultpod = apiInstance.readNamespacedPod(podname, namespace, "true", true, true);
        } catch (ApiException e) {
            System.out.println();
        }
        return resultpod;

    }

    /**
     * 根据podname 获取pod 中镜像列表
     * @param namespace 命名空间
     * @param podname pod名称
     * @return 日志结果

     */
    public static List<V1Container> getPodContainers(String namespace, String podname) {
        System.out.println("podnameL "+podname+"    namespace: "+namespace);
        CoreV1Api apiInstance = new CoreV1Api(kubeClient);
        V1Pod resultpod;
        List<V1Container> containers1 = null;
        try {
            resultpod = apiInstance.readNamespacedPod(podname, namespace, "true", true, true);
            System.out.println(resultpod);
            containers1 = resultpod.getSpec().getContainers();
            System.out.println("containers");
            System.out.println(containers1);

        } catch (ApiException e) {
            System.out.println(e);
        }
        return containers1;

    }


    /**
     * 根据podname 获取pod ，获取pod中容器个数，获取每个容器的日志，返回日志结果
     * @param namespace 命名空间
     * @return 日志结果
     * @throws IOException
     * @throws ApiException
     */
    public static void watchWorkflowlog(String namespace,String workflowName,OutputStream outputStream) throws IOException{
        Map<String,String> workflowcontent = new HashMap<String,String>();//日志
        StringBuilder sbmain = new StringBuilder();
        StringBuilder sbinit = new StringBuilder();
        StringBuilder sbwait = new StringBuilder();

        //根据提交后的工作流名称获取该工作流完整信息
        Workflow successworkflow = null;
        try {
            successworkflow = ArgoUtils.getWorkflow(namespace, workflowName);
            //创建一个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 = 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中镜像为空");
                        }
                    }
                }

            }

        } catch (io.argoproj.workflow.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);

        outputStream.write(paramjson.getBytes());
//        MyWebSocket.sendMessage(paramjson);
//        if(successworkflow.getStatus().getPhase().equals("Succeed"))

//        kubeClient.pods().inNamespace(namespace).withName(podName).tailingLines(10).watchLog(System.out);

    }





}
