package cn.qg.qaplatform.utils;

import io.fabric8.kubernetes.api.model.Pod;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.api.model.ServicePort;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

@Slf4j
@Component
public class K8sService {

    private KubernetesClient kubernetesClient;

    public K8sService() {
        try {
            String configYAML = String.join("\n", readConfigFile("kube-config.yml"));
            Config config = Config.fromKubeconfig(configYAML);
            kubernetesClient = new DefaultKubernetesClient(config);
            String configCrt = String.join("\n", readConfigFile("tke-cluster-ca.crt"));
            config.setCaCertData(configCrt);
            log.info("k8s连接初始化成功！");
        } catch (Exception e) {
            log.info("k8s service 初始化失败！");
            e.printStackTrace();
        }
    }

    /**
     * 读取k8s配置文件
     * @param file 配置文件名
     * @return
     * @throws IOException
     */
    private static List<String> readConfigFile(String file) throws IOException {
        String str = "";
        ClassPathResource resource = new ClassPathResource(file);
        InputStream in = resource.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        List<String> result = new ArrayList<>();
        while ((str = br.readLine()) != null) {
            result.add(str);
        }
        return result;
    }

    /**
     * 获取环境的所有k8s变量
     * @param namespace 环境
     */
    public Map<String, Object> getListEnvVars(String namespace) {
        Map<String, Object> envMap = new TreeMap<>();
        List<Pod> podList = kubernetesClient.pods().inNamespace(namespace).list().getItems();
        List<Service> serviceList = kubernetesClient.services().inNamespace(namespace).list().getItems();
        // 遍历Pod列表
        for (Pod pod: podList) {
            if (!pod.getStatus().getPhase().equals("Failed")) {
                String serviceName = pod.getMetadata().getLabels().get("qcloud-app");
                serviceName = serviceName.replace("-", "_").toUpperCase();
                envMap.put(serviceName + "_SERVICE_HOST", pod.getStatus().getHostIP());
                // MYSQL需要额外加个参数
                if (serviceName.equals("MYSQL")) {
                    envMap.put("DB_SERVICE_HOST", pod.getStatus().getHostIP());
                }
            }
        }
        // 遍历Service列表
        for (Service service: serviceList) {
            String serviceName = service.getMetadata().getName().toUpperCase().replaceAll("-", "_");
            List<ServicePort> servicePortList = service.getSpec().getPorts();
            if (service.getMetadata().getLabels().get("type").equals("base")) {
                if (servicePortList.get(0).getPort() != null) {
                    envMap.put(serviceName + "_SERVICE_PORT", servicePortList.get(0).getNodePort());
                    // MYSQL需要额外加个参数
                    if (serviceName.equals("MYSQL")) {
                        envMap.put("DB_SERVICE_PORT", servicePortList.get(0).getNodePort());
                    }
                }
                for (ServicePort servicePort: servicePortList) {
                    envMap.put(serviceName + "_SERVICE_PORT_" + servicePort.getPort(), servicePort.getNodePort());
                    // MYSQL需要额外加个参数
                    if (serviceName.equals("MYSQL")) {
                        envMap.put("DB_SERVICE_PORT_" + servicePort.getPort(), servicePort.getNodePort());
                    }
                }
            } else {
                if (servicePortList.get(0).getNodePort() != null) {
                    envMap.put(serviceName + "_SERVICE_PORT", servicePortList.get(0).getNodePort());
                }
                for (ServicePort servicePort: servicePortList) {
                    if (service.getSpec().getType().equals("NodePort")) {
                        envMap.put(serviceName + "_SERVICE_PORT_" + servicePort.getPort(), servicePort.getNodePort());
                    } else if (service.getSpec().getType().equals("ClusterIP")) {
                        envMap.put(serviceName + "_SERVICE_PORT_" + servicePort.getName(), servicePort.getPort());
                    }
                }
            }
        }
        return envMap;
    }
}
