package com.ruoyi.platform.utils;

import com.ruoyi.system.api.constant.Constant;
import com.ruoyi.platform.domain.ComputingResource;
import com.ruoyi.platform.domain.DevEnvironment;
import com.ruoyi.platform.mapper.ComputingResourceDao;
import com.ruoyi.platform.service.ResourceOccupyService;
import io.kubernetes.client.Exec;
import io.kubernetes.client.custom.IntOrString;
import io.kubernetes.client.custom.Quantity;
import io.kubernetes.client.openapi.ApiClient;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.*;
import io.kubernetes.client.util.ClientBuilder;
import io.kubernetes.client.util.Config;
import io.kubernetes.client.util.credentials.AccessTokenAuthentication;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

/**
 * k8s客户端
 *
 * @author fans
 * @date 2021/6/18 14:14
 */
@Slf4j
@Component
public class K8sClientUtil {

    @Value("${jupyter.hostPath}")
    private String hostPath;
    @Value("${dockerpush.proxyUrl}")
    private String proxyUrl;
    @Value("${proxy.useProxy:false}")
    private boolean useProxy;

    @Value("${git.localPath}")
    String localPathlocal;

    private String http;
    private String token;
    /**
     * k8s-api客户端
     */
    private static ApiClient apiClient;

    @Resource
    private ResourceOccupyService resourceOccupyService;

    @Resource
    private ComputingResourceDao computingResourceDao;

    /**
     * 构建集群POD内通过SA访问的客户端
     * loading the in-cluster config, including:
     * 1. service-account CA
     * 2. service-account bearer-token
     * 3. service-account namespace
     * 4. master endpoints(ip, port) from pre-set environment variables
     */
    @Autowired
    public K8sClientUtil(@Value("${k8s.http}") String http, @Value("${k8s.token}") String token) {
        this.http = http;
        this.token = token;
        try {
//            this.apiClient = new ClientBuilder().
//                    setBasePath(http).setVerifyingSsl(false).
//                    setAuthentication(new AccessTokenAuthentication(token)).build();
            this.apiClient = Config.fromCluster();
        } catch (Exception e) {
            log.error("构建K8s-Client异常", e);
            throw new RuntimeException("构建K8s-Client异常");
        }
    }
//    @Autowired
//    public K8sClientUtil() {
//        try {
//            this.apiClient = new ClientBuilder().
//                    setBasePath(http).setVerifyingSsl(false).
//                    setAuthentication(new AccessTokenAuthentication(token)).build();
//        } catch (Exception e) {
//            log.error("构建K8s-Client异常", e);
//            throw new RuntimeException("构建K8s-Client异常");
//        }
//    }
//    @PostConstruct
//    public void init() {
//            this.apiClient = new ClientBuilder().
//                    setBasePath(http).setVerifyingSsl(false).
//                    setAuthentication(new AccessTokenAuthentication(token)).build();
//     }

    /**
     * 构建集群外通过UA访问的客户端
     * loading the out-of-cluster config, a kubeconfig from file-system
     *
     * @param kubeConfigPath kube连接配置文件
     */
//    public K8sClientUtil() {
//        try {
//            this.apiClient = new ClientBuilder().
//                    setBasePath("https://172.20.32.181:6443").setVerifyingSsl(false).
//                    setAuthentication(new AccessTokenAuthentication("eyJhbGciOiJSUzI1NiIsImtpZCI6IjRWcFBPWl9YSFFxQ2tVanRuNHdRT1dnUlJNTnB2bG5TQlVSRjNKdExWNDQifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImFkbWluLXNlcnZpY2UtYWNjb3VudC10b2tlbi14ZDk5eiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbi1zZXJ2aWNlLWFjY291bnQiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJmMGEzNmYyMS01MjQyLTQ4MTAtYWVmZS0xOTEwOTZlZjc5YmUiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDphZG1pbi1zZXJ2aWNlLWFjY291bnQifQ.fo-Wf0-5-IRC5fhRh65yfqCJqKfE9MrNFIXL2fd1CqVAHD7JBpWO2IsFiSmz9Bm7VfLmFAp2NB7DjW4ZLjC7ODiGhpSseBP8x4ceFuHL6pRGUsEBvHQBBBuQcGhNOcsxIDHnDqUdUzoLprj223lMZNTQowITuqYFU4GVbethyEuS6G5Wh9KHI3KYHFtG4_AeWBgI5Ppz8pDrhHzSFWTFbzxQ3RPGEwF0V-9wEtdrSYnfETi3rdRWif9W4a0RW8HwD9Gf7UCYcyFOs7e5_3-IvmctS85g87PYIfHXMhu_kOw-_Il4bkwPEK5uiBFDw0M1-s9YP-F9r5sXXvOJlsAr1g")).build();
//        } catch (Exception e) {
//            log.error("构建K8s-Client异常", e);
//            throw new RuntimeException("构建K8s-Client异常");
//        }
//    }

    /**
     * 获取所有的Pod
     *
     * @return podList
     */
    public static V1PodList getAllPodList() {
        // new a CoreV1Api
        CoreV1Api api = new CoreV1Api(apiClient);

        // invokes the CoreV1Api client
        try {
            V1PodList list = api.listPodForAllNamespaces(null, null, null, null, null, null, null, null, null, null);
            return list;
        } catch (ApiException e) {
            log.error("获取podlist异常:" + e.getResponseBody(), e);
        }
        return null;
    }

    /**
     * 创建k8s service
     *
     * @param namespace   命名空间
     * @param serviceName 服务名称
     * @param port        服务端口号（和目标pod的端口号一致）
     * @param selector    pod标签选择器
     * @return 创建成功的service对象
     */
    public static V1Service createService(String namespace, String serviceName, Integer port, Map<String, String> selector) {
        //构建service的yaml对象
        CoreV1Api api = new CoreV1Api(apiClient);
        V1ServiceList v1ServiceList = null;
        try {
            v1ServiceList = api.listNamespacedService(namespace, null, null, null, null, null, null, null, null, null, null);
        } catch (ApiException e) {
            log.error("获取 SVC 异常:", e);
        }
        if (v1ServiceList != null) {
            for (V1Service svc : v1ServiceList.getItems()) {
                if (StringUtils.equals(svc.getMetadata().getName(), serviceName)) {
                    // SVC 已存在
                    return svc;
                }
            }
        }


        V1Service svc = new V1ServiceBuilder()
                .withNewMetadata()
                .withName(serviceName)
                .withLabels(selector)
                .endMetadata()
                .withNewSpec()
                .withType("NodePort")
                .addNewPort()
                .withProtocol("TCP")
                .withPort(port)
                .withTargetPort(new IntOrString(port))
                .withNodePort(0)
                .endPort()
                .withSelector(selector)
                .endSpec()
                .build();


        svc.getSpec().setSelector(selector);
        // Deployment and StatefulSet is defined in apps/v1, so you should use AppsV1Api instead of CoreV1API
        V1Service v1Service = null;
        try {
            v1Service = api.createNamespacedService(namespace, svc, null, null, null);
        } catch (ApiException e) {
            log.error("创建service异常:" + e.getResponseBody(), e);
        } catch (Exception e) {
            log.error("创建service系统异常:", e);
        }
        return v1Service;
    }

    /**
     * 创建k8s PVC
     *
     * @param namespace 命名空间
     * @param pvcName   服务名称
     * @return 创建成功的service对象
     */
    public V1PersistentVolumeClaim createPvc(String namespace, String pvcName, String storage, String storageClassName) {
        CoreV1Api api = new CoreV1Api(apiClient);

        V1PersistentVolumeClaimList pvcList = null;
        try {
            pvcList = api.listNamespacedPersistentVolumeClaim(namespace, null, null, null, null, null, null, null, null, null, null);
        } catch (ApiException e) {
            log.error("获取 PVC 异常:", e);
        }
        if (pvcList != null) {
            for (V1PersistentVolumeClaim pvc1 : pvcList.getItems()) {
                if (StringUtils.equals(pvc1.getMetadata().getName(), pvcName)) {
                    // PVC 已存在
                    return pvc1;
                }
            }
        }
        V1PersistentVolumeClaim pvc = null;
        Map<String, Quantity> requests = new HashMap<String, Quantity>();
        requests.put("storage", new Quantity(storage));
        pvc = new V1PersistentVolumeClaimBuilder()
                .withNewMetadata()
                .withName(pvcName)
                .endMetadata()
                .withNewSpec()
                .withAccessModes("ReadWriteOnce")
                .withStorageClassName(storageClassName)
                .withResources(new V1ResourceRequirementsBuilder()
                        .withRequests(requests)
                        .build())
                .endSpec()
                .build();

        try {
            pvc = api.createNamespacedPersistentVolumeClaim(namespace, pvc, null, null, null);
        } catch (ApiException e) {
            log.error("创建pvc异常:" + e.getResponseBody(), e);
        } catch (Exception e) {
            log.error("创建pvc系统异常:", e);
        }
        return pvc;
    }


    /**
     * 创建k8s 临时POD
     *
     * @param podName   pod name
     * @param namespace 命名空间
     * @param port      port
     * @param mountPath 映射路径
     * @param pvc       存储
     * @param image     镜像
     * @return 创建成功的pod，的nodePort端口
     */

    public Integer createPod(String podName, String namespace, Integer port, String mountPath, V1PersistentVolumeClaim pvc, String image) {

        Map<String, String> selector = new LinkedHashMap<String, String>();
        selector.put("k8s-jupyter", podName);

        CoreV1Api api = new CoreV1Api(apiClient);
        V1PodList v1PodList = null;
        try {
            v1PodList = api.listNamespacedPod(namespace, null, null, null, null, null, null, null, null, null, null);
        } catch (ApiException e) {
            log.error("获取 POD 异常:", e);
        }
        if (v1PodList != null) {
            for (V1Pod pod1 : v1PodList.getItems()) {
                if (StringUtils.equals(pod1.getMetadata().getName(), podName)) {
                    // PVC 已存在

                    V1Service service = createService(namespace, podName + "-svc", port, selector);
                    if (service != null) {
                        return service.getSpec().getPorts().get(0).getNodePort();
                    }
                }
            }
        }

        V1Pod pod = new V1PodBuilder()
                .withNewMetadata()
                .withName(podName)
                .withLabels(selector)
                .endMetadata()
                .withNewSpec() //默认不被操作4小时后删除
                .addNewContainer()
                .withName(podName)
                .withImage(image)
                .withPorts(new V1ContainerPort().containerPort(port).protocol("TCP"))
                .withVolumeMounts(new V1VolumeMount().name("workspace").mountPath(mountPath))
                .endContainer()
                .addNewVolume()
                .withName("workspace").withPersistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvc.getMetadata().getName()))
                .endVolume()
                .withTerminationGracePeriodSeconds(14400L)  //默认不被操作4小时后删除
                .endSpec()
                .build();

        try {
            pod = api.createNamespacedPod(namespace, pod, null, null, null);
        } catch (ApiException e) {
            log.error("创建pod异常:" + e.getResponseBody(), e);
        } catch (Exception e) {
            log.error("创建pod系统异常:", e);

        }

        V1Service service = createService(namespace, podName + "-svc", port, selector);
        return service.getSpec().getPorts().get(0).getNodePort();
    }


    /**
     * 创建k8s 临时POD
     *
     * @param podName   pod name
     * @param namespace 命名空间
     * @param port      port
     * @param mountPath 映射路径
     * @param subPath   pvc子路径
     * @param image     镜像
     * @return 创建成功的pod，的nodePort端口
     */
//    public Integer createPodWithSubPath(String podName, String namespace, Integer port, String mountPath, String subPath, String pvcName, String image) {
    public Integer createPodWithSubPath(String podName, String namespace, Integer port, String mountPath, String subPath, String image) {

        Map<String, String> selector = new LinkedHashMap<>();
        selector.put("k8s-jupyter", podName);

        CoreV1Api api = new CoreV1Api(apiClient);
        V1PodList v1PodList = null;
        try {
            v1PodList = api.listNamespacedPod(namespace, null, null, null, null, null, null, null, null, null, null);
        } catch (ApiException e) {
            log.error("获取 POD 异常:", e);
        }
        if (v1PodList != null) {
            for (V1Pod pod1 : v1PodList.getItems()) {
                if (StringUtils.equals(pod1.getMetadata().getName(), podName)) {
                    // PVC 已存在
                    V1Service service = createService(namespace, podName + "-svc", port, selector);
                    if (service != null) {
                        return service.getSpec().getPorts().get(0).getNodePort();
                    }
                }
            }
        }

        int lastIndex = hostPath.lastIndexOf('/');
        String newPath = hostPath.substring(0, lastIndex);
        V1Pod pod;

        V1HTTPGetAction httpGetAction = new V1HTTPGetAction().path("/").port(new IntOrString(port));
        V1Probe readinessProbe = new V1Probe().httpGet(httpGetAction).initialDelaySeconds(10).periodSeconds(5).failureThreshold(2);

        if (useProxy) {
            pod = new V1PodBuilder()
                    .withNewMetadata()
                    .withName(podName)
                    .withLabels(selector)
                    .endMetadata()
                    .withNewSpec()
                    .addNewContainer()
                    .withName(podName)
                    .withImage(image)
                    .withPorts(new V1ContainerPort().containerPort(port).protocol("TCP"))
                    .withVolumeMounts(new V1VolumeMount().name("workspace").mountPath(mountPath).subPath(subPath))
                    .withNewSecurityContext().withNewPrivileged(true).endSecurityContext()
                    .withReadinessProbe(readinessProbe)
                    .addNewEnv()
                    .withName("HTTP_PROXY")
                    .withValue(proxyUrl)
                    .endEnv()
                    .addNewEnv()
                    .withName("HTTPS_PROXY")
                    .withValue(proxyUrl)
                    .endEnv()
                    .addNewEnv()
                    .withName("NO_PROXY")
                    .withValue("localhost,kubernetes.default.svc")
                    .endEnv()
                    .endContainer()
                    .addNewVolume()
                    .withName("workspace")
                    .withHostPath(new V1HostPathVolumeSource().path(newPath).type("DirectoryOrCreate"))
//                .withPersistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvcName))
                    .endVolume()
                    .withTerminationGracePeriodSeconds(14400L)
                    .endSpec()
                    .build();
        } else {
            pod = new V1PodBuilder()
                    .withNewMetadata()
                    .withName(podName)
                    .withLabels(selector)
                    .endMetadata()
                    .withNewSpec()
                    .addNewContainer()
                    .withName(podName)
                    .withImage(image)
                    .withPorts(new V1ContainerPort().containerPort(port).protocol("TCP"))
                    .withVolumeMounts(new V1VolumeMount().name("workspace").mountPath(mountPath).subPath(subPath))
                    .withNewSecurityContext().withNewPrivileged(true).endSecurityContext()
                    .withReadinessProbe(readinessProbe)
                    .addNewEnv()
                    .withName("NO_PROXY")
                    .withValue("localhost,kubernetes.default.svc")
                    .endEnv()
                    .endContainer()
                    .addNewVolume()
                    .withName("workspace")
                    .withHostPath(new V1HostPathVolumeSource().path(newPath).type("DirectoryOrCreate"))
//                .withPersistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvcName))
                    .endVolume()
                    .withTerminationGracePeriodSeconds(14400L)
                    .endSpec()
                    .build();
        }

        try {
            pod = api.createNamespacedPod(namespace, pod, null, null, null);
        } catch (ApiException e) {
            log.error("创建pod异常:" + e.getResponseBody(), e);
        } catch (Exception e) {
            log.error("创建pod系统异常:", e);
        }

        V1Service service = createService(namespace, podName + "-svc", port, selector);
        return service.getSpec().getPorts().get(0).getNodePort();
    }

    // 创建配置好的Pod
    public Integer createConfiguredPod(String podName, String namespace, Integer port, String mountPath, V1PersistentVolumeClaim pvc, DevEnvironment devEnvironment, String dataPvcName, String datasetPath, String modelPath) throws IOException {

        //设置选择节点，pod反亲和性
        Map<String, String> selector = new LinkedHashMap<>();
        Map<String, String> nodeSelector = new LinkedHashMap<>();
        V1Affinity v1Affinity = new V1Affinity();
        if (Constant.Computing_Resource_GPU.equals(devEnvironment.getComputingResource())) {
            selector.put("k8s-jupyter", "CPU-GPU");
            nodeSelector.put("resource-type", "CPU-GPU");

            V1LabelSelectorRequirement labelSelectorRequirement = new V1LabelSelectorRequirement()
                    .key("k8s-jupyter").operator("NotIn").values(Collections.singletonList("CPU-GPU"));

            V1LabelSelector labelSelector = new V1LabelSelector()
                    .matchExpressions(Collections.singletonList(labelSelectorRequirement));

            V1PodAffinityTerm podAffinityTerm = new V1PodAffinityTerm()
                    .labelSelector(labelSelector)
                    .namespaces(Collections.singletonList(namespace))
                    .topologyKey("kubernetes.io/hostname");

            V1PodAffinity podAffinity = new V1PodAffinity()
                    .requiredDuringSchedulingIgnoredDuringExecution(Collections.singletonList(podAffinityTerm));

            V1LabelSelectorRequirement antiLabelSelectorRequirement = new V1LabelSelectorRequirement()
                    .key("k8s-jupyter").operator("In").values(Collections.singletonList("CPU-GPU"));

            V1LabelSelector antiLabelSelector = new V1LabelSelector()
                    .matchExpressions(Collections.singletonList(antiLabelSelectorRequirement));

            V1PodAffinityTerm antiPodAffinityTerm = new V1PodAffinityTerm()
                    .labelSelector(antiLabelSelector)
                    .namespaces(Collections.singletonList(namespace))
                    .topologyKey("kubernetes.io/hostname");

            V1PodAntiAffinity podAntiAffinity = new V1PodAntiAffinity()
                    .requiredDuringSchedulingIgnoredDuringExecution(Collections.singletonList(antiPodAffinityTerm));

            v1Affinity.podAffinity(podAffinity).podAntiAffinity(podAntiAffinity);
        } else {
            selector.put("k8s-jupyter", "CPU");
        }

        // 创建Pod
        CoreV1Api api = new CoreV1Api(apiClient);
        V1PodList v1PodList = null;
        try {
            v1PodList = api.listNamespacedPod(namespace, null, null, null, null, null, null, null, null, null, null);
        } catch (ApiException e) {
            log.error("获取 POD 异常:", e);
        }
        if (v1PodList != null) {
            for (V1Pod pod1 : v1PodList.getItems()) {
                // Pod 已存在
                if (StringUtils.equals(pod1.getMetadata().getName(), podName)) {
                    V1Service service = createService(namespace, podName + "-svc", port, selector);
                    if (service != null) {
                        return service.getSpec().getPorts().get(0).getNodePort();
                    }
                }
            }
        }

        // 配置卷和卷挂载
        List<V1VolumeMount> volumeMounts = new ArrayList<>();
        volumeMounts.add(new V1VolumeMount().name("workspace").mountPath("/opt/notebooks"));

        List<V1Volume> volumes = new ArrayList<>();
        volumes.add(new V1Volume().name("workspace").hostPath(new V1HostPathVolumeSource().path(hostPath + "/" + podName + "/notebooks").type("DirectoryOrCreate")));

        if (StringUtils.isNotEmpty(datasetPath)) {
            volumeMounts.add(new V1VolumeMount().name("data").mountPath("/opt/dataset").subPath(datasetPath).readOnly(true));
        }
        if (StringUtils.isNotEmpty(modelPath)) {
            volumeMounts.add(new V1VolumeMount().name("data").mountPath("/opt/model").subPath(modelPath).readOnly(true));
        }
        if (StringUtils.isNotEmpty(datasetPath) || StringUtils.isNotEmpty(modelPath)) {
            volumes.add(new V1Volume().name("data").hostPath(new V1HostPathVolumeSource().path(hostPath).type("DirectoryOrCreate")));
        }

        // 配置卷和卷挂载
//        List<V1VolumeMount> volumeMounts = new ArrayList<>();
//        volumeMounts.add(new V1VolumeMount().name("workspace").mountPath(mountPath));
//        volumeMounts.add(new V1VolumeMount().name("minio-pvc").mountPath("/opt/data").subPath(datasetPath).readOnly(true));
//        volumeMounts.add(new V1VolumeMount().name("minio-pvc").mountPath("/opt/model").subPath(modelPath).readOnly(true));
//
//        List<V1Volume> volumes = new ArrayList<>();
//        volumes.add(new V1Volume().name("workspace").persistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvc.getMetadata().getName())));
//        volumes.add(new V1Volume().name("minio-pvc").persistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(dataPvcName)));


        //配置资源
        V1ResourceRequirements v1ResourceRequirements = setPodResource(devEnvironment.getComputingResourceId());
        V1HTTPGetAction httpGetAction = new V1HTTPGetAction().path("/").port(new IntOrString(port));
        V1Probe readinessProbe = new V1Probe().httpGet(httpGetAction).initialDelaySeconds(10).periodSeconds(5).failureThreshold(2);

        String image = (String) JsonUtils.jsonToMap(devEnvironment.getImage()).get("value");

        V1Pod pod = new V1PodBuilder()
                .withNewMetadata()
                .withName(podName)
                .withLabels(selector)
                .endMetadata()
                .withNewSpec()
                .addNewContainer()
                .withName(podName)
                .withImage(image)
                .withPorts(new V1ContainerPort().containerPort(port).protocol("TCP"))
                .withVolumeMounts(volumeMounts)
                .withResources(v1ResourceRequirements)
                .withReadinessProbe(readinessProbe)
                .endContainer()
                .withVolumes(volumes)
                .withNodeSelector(nodeSelector)
                .withAffinity(v1Affinity)
                .endSpec()
                .build();

        try {
            // 记录开始扣积分
            if (resourceOccupyService.haveResource(devEnvironment.getComputingResourceId(), 1)) {
                pod = api.createNamespacedPod(namespace, pod, null, null, null);
                String nodeName = getNodeName(podName, namespace);

                // 记录开始扣除积分
                resourceOccupyService.startDeduce(devEnvironment.getComputingResourceId(), 1, Constant.TaskType_Dev, Long.valueOf(devEnvironment.getId()), null, null, devEnvironment.getName(), null, null);
            }
        } catch (ApiException e) {
            throw new RuntimeException("创建pod异常:" + e.getResponseBody());
        } catch (Exception e) {
            throw new RuntimeException("创建pod系统异常:" + e.getMessage());
        }

        V1Service service = createService(namespace, podName + "-svc", port, selector);
        return service.getSpec().getPorts().get(0).getNodePort();
    }


    /**
     * 根据获取namespace,deploymentName的Pod Name
     *
     * @return podList
     */
    public V1Pod getNSPodList(String namespace, String deploymentName) throws Exception {
        // new a CoreV1Api
        CoreV1Api api = new CoreV1Api(apiClient);
        V1PodList v1PodList = null;
        try {
            v1PodList = api.listNamespacedPod(namespace, null, null, null, null, null, null, null, null, null, null);
        } catch (ApiException e) {
            log.error("获取 POD 异常:", e);
        }
        // invokes the CoreV1Api client
        if (v1PodList != null) {
            for (V1Pod item : v1PodList.getItems()) {
                String generateName = item.getMetadata().getName();
                if (StringUtils.isNotEmpty(generateName) && generateName.startsWith(deploymentName)) {
                    // 找到匹配的Pod，获取其名称
                    return item;
                }
            }
        }
        return null;
    }

    public String executeCommand(V1Pod item, String command) {
        try {
            // 创建API实例
            // 创建Exec实例
            Exec exec = new Exec(apiClient);
            String[] cmd = {"/bin/sh", "-c", command};
            Process proc = exec.exec(item, cmd, false);
            // 读取输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            StringBuilder builder = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                builder.append(line);
                builder.append(System.getProperty("line.separator"));
            }
            // 等待进程结束，并获取退出值
            int exitValue = proc.waitFor();
            if (exitValue != 0) {
                // 如果进程的退出值不为0，表示命令执行失败
                throw new RuntimeException("容器中命令执行失败，退出值：" + exitValue);
            }
            return builder.toString();
        } catch (Exception e) {
            log.error("容器执行命令异常", e);
            throw new RuntimeException("容器执行命令异常");
        }
    }

    /**
     * 根据Pod的名称和Namespace查询Pod的状态
     *
     * @param podName   Pod的名称
     * @param namespace Pod所在的Namespace
     */
    public String getPodStatus(String podName, String namespace) throws Exception {
        CoreV1Api api = new CoreV1Api(apiClient);
        V1Pod pod = api.readNamespacedPod(podName, namespace, null, null, null);
        String status = pod.getStatus().getPhase();
        Boolean podReady = false;

        List<V1PodCondition> conditions = pod.getStatus().getConditions();
        if (conditions != null) {
            for (V1PodCondition condition : conditions) {
                if (Constant.Ready.equals(condition.getType()) && Constant.True.equals(condition.getStatus())) {
                    podReady = true;
                    break;
                }
            }
        }

        if (Constant.Running.equals(status) && !podReady) {
            return Constant.Pending;
        }
        return status;
    }

    /**
     * 根据Pod的名称和Namespace查询Pod的容器信息
     *
     * @param podName   Pod的名称
     * @param namespace Pod所在的Namespace
     */
    public String getPodContainerId(String podName, String namespace) throws Exception {
        CoreV1Api api = new CoreV1Api(apiClient);
        V1Pod pod = api.readNamespacedPod(podName, namespace, null, null, null);

        if (pod.getStatus().getContainerStatuses().size() != 1) {
            throw new RuntimeException("容器错误");
        }
        String containerId = pod.getStatus().getContainerStatuses().get(0).getContainerID().split("//")[1];
        return containerId;
    }

    public String getHostIp(String podName, String namespace) throws Exception {
        CoreV1Api api = new CoreV1Api(apiClient);
        V1Pod pod = api.readNamespacedPod(podName, namespace, null, null, null);
        return pod.getStatus().getHostIP();
    }

    public String getNodeName(String podName, String namespace) throws Exception {
        CoreV1Api api = new CoreV1Api(apiClient);
        V1Pod pod = api.readNamespacedPod(podName, namespace, null, null, null);
        return pod.getSpec().getNodeName();
    }

    public String getPodLogs(String podName, String namespace, String container, int line) {
        CoreV1Api api = new CoreV1Api(apiClient);
        try {
            String log = api.readNamespacedPodLog(podName, namespace, StringUtils.isEmpty(container) ? null : container, null, null, null, null, null, null, line, null);
            return log;
        } catch (ApiException e) {
            throw new RuntimeException("获取Pod日志异常", e);
        }

    }


    public V1Pod createPodWithEnv(String podName, String namespace, String mountPath, String image) {
        CoreV1Api api = new CoreV1Api(apiClient);

        V1SecurityContext v1SecurityContext = new V1SecurityContext();
        v1SecurityContext.setPrivileged(true);

        // 配置卷和卷挂载
        List<V1VolumeMount> volumeMounts = new ArrayList<>();
        volumeMounts.add(new V1VolumeMount().name("workspace").mountPath(mountPath));

        List<V1Volume> volumes = new ArrayList<>();
        volumes.add(new V1Volume().name("workspace").hostPath(new V1HostPathVolumeSource().path(hostPath + "/images").type("DirectoryOrCreate")));
        V1Pod pod;
        if (useProxy) {
            pod = new V1PodBuilder()
                    .withNewMetadata()
                    .withName(podName)
                    .endMetadata()
                    .withNewSpec()
                    .addNewContainer()
                    .withName(podName)
                    .withImage(image) // 替换为您实际要使用的镜像名称
                    .withSecurityContext(v1SecurityContext)
//                .withVolumeMounts(new V1VolumeMount().name("workspace").mountPath(mountPath))
                    .withVolumeMounts(volumeMounts)
                    .withNewSecurityContext().withNewPrivileged(true).endSecurityContext()
                    .addNewEnv()
                    .withName("HTTP_PROXY")
                    .withValue(proxyUrl)
                    .endEnv()
                    .addNewEnv()
                    .withName("HTTPS_PROXY")
                    .withValue(proxyUrl)
                    .endEnv()
                    .addNewEnv()
                    .withName("NO_PROXY")
                    .withValue("localhost,kubernetes.default.svc")
                    .endEnv()
                    .endContainer()
//                .addNewVolume()
//                .withName("workspace").withPersistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvcName))
//                .endVolume()
                    .withVolumes(volumes)
                    .endSpec()
                    .build();
        } else {
            pod = new V1PodBuilder()
                    .withNewMetadata()
                    .withName(podName)
                    .endMetadata()
                    .withNewSpec()
                    .addNewContainer()
                    .withName(podName)
                    .withImage(image) // 替换为您实际要使用的镜像名称
                    .withSecurityContext(v1SecurityContext)
//                .withVolumeMounts(new V1VolumeMount().name("workspace").mountPath(mountPath))
                    .withVolumeMounts(volumeMounts)
                    .withNewSecurityContext().withNewPrivileged(true).endSecurityContext()
                    .addNewEnv()
                    .withName("NO_PROXY")
                    .withValue("localhost,kubernetes.default.svc")
                    .endEnv()
                    .endContainer()
//                .addNewVolume()
//                .withName("workspace").withPersistentVolumeClaim(new V1PersistentVolumeClaimVolumeSource().claimName(pvcName))
//                .endVolume()
                    .withVolumes(volumes)
                    .endSpec()
                    .build();
        }

        try {
            pod = api.createNamespacedPod(namespace, pod, null, null, null);
        } catch (ApiException e) {
            log.error("创建pod异常:" + e.getResponseBody(), e);
        } catch (Exception e) {
            log.error("创建pod系统异常:", e);
        }
        return pod;
    }


    V1ResourceRequirements setPodResource(Integer computingResourceId) {
        ComputingResource computingResource = computingResourceDao.queryById(computingResourceId);

        //配置pod资源
        String memory = computingResource.getMemoryGb().toString().concat("Gi");
        HashMap<String, Quantity> limitMap = new HashMap<>();
        if (computingResource.getGpuNums() != null && computingResource.getGpuNums() != 0) {
            limitMap.put("nvidia.com/gpu", new Quantity(String.valueOf(computingResource.getGpuNums())));
        }
        limitMap.put("cpu", new Quantity(String.valueOf(computingResource.getCpuCores())));
        limitMap.put("memory", new Quantity(memory));
        limitMap.put("ephemeral-storage", new Quantity("20Gi"));

        V1ResourceRequirements v1ResourceRequirements = new V1ResourceRequirements();
        v1ResourceRequirements.setRequests(limitMap);
        v1ResourceRequirements.setLimits(limitMap);

        return v1ResourceRequirements;
    }

    /**
     * 删除 Pod
     *
     * @param podName   Pod 名称
     * @param namespace 命名空间
     * @throws ApiException 异常
     */
    public String deletePod(String podName, String namespace) throws ApiException {
        CoreV1Api api = new CoreV1Api(apiClient);
        try {
            V1Pod pod = api.deleteNamespacedPod(podName, namespace, null, null, null, null, null, null);
            return "Pod " + podName + " 删除请求已发送";
        } catch (ApiException e) {
            log.error("删除pod异常:" + e.getResponseBody(), e);
            throw e;
        }
    }


    /**
     * 删除 Service
     *
     * @param svcName   Service 名称
     * @param namespace 命名空间
     * @throws ApiException 异常
     */
    public String deleteService(String svcName, String namespace) throws ApiException {
        CoreV1Api api = new CoreV1Api(apiClient);
        try {
            V1Status result = api.deleteNamespacedService(svcName, namespace, null, null, null, null, null, null);
            return "Service " + svcName + " 删除请求已发送";
        } catch (ApiException e) {
            log.error("删除service异常:" + e.getResponseBody(), e);
            throw e;
        }
    }


    /**
     * 检查 Pod 是否存在
     *
     * @param podName   Pod 名称
     * @param namespace 命名空间
     * @return 是否存在
     * @throws ApiException 异常
     */
    public boolean checkPodExists(String podName, String namespace) throws ApiException {
        CoreV1Api api = new CoreV1Api(apiClient);
        try {
            api.readNamespacedPod(podName, namespace, null, false, false);
            return true;
        } catch (ApiException e) {
            if (e.getCode() == 404) {
                return false;
            } else {
                log.error("检查pod存在性异常:" + e.getResponseBody(), e);
                throw e;
            }
        }
    }


}
