package com.ruoyi.platform.utils;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.CommitCmd;
import com.github.dockerjava.api.command.InspectImageResponse;
import com.github.dockerjava.api.model.AuthConfig;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
import com.github.dockerjava.transport.DockerHttpClient;
import com.ruoyi.platform.vo.ImageVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.HashMap;

@Slf4j
@Component
public class DockerClientUtil {

    @Value("${harbor.bucketName}")
    private String bucketName;
    @Value("${harbor.repository}")
    private String repository;
    @Value("${harbor.harborUrl}")
    private String harborUrl;
    @Value("${harbor.harborUser}")
    private String harborUser;
    @Value("${harbor.harborpassword}")
    private String harborpassword;

    public DockerClient getDockerClient(String dockerServerUrl) {

        //创建DefaultDockerClientConfig（指定docker服务器的配置）
        DockerClientConfig config = DefaultDockerClientConfig
                .createDefaultConfigBuilder()
                .withDockerHost("tcp://" + dockerServerUrl + ":2375")
                .withDockerTlsVerify(false)
                .withApiVersion("1.40")
//                .withDockerCertPath(dcokerCertPath)
//                .withRegistryUsername(registryUser)
//                .withRegistryPassword(registryPass)
//                .withRegistryEmail(registryMail)
//                .withRegistryUrl(registryUrl)
                .build();

        //创建DockerHttpClient
        DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder()
                .dockerHost(config.getDockerHost())
                .sslConfig(config.getSSLConfig())
                .maxConnections(1000)
                .connectionTimeout(Duration.ofSeconds(300))
                .responseTimeout(Duration.ofSeconds(450))
                .build();

        //创建DockerClient
        return DockerClientImpl.getInstance(config, httpClient);

    }

    public String commitImage(ImageVo imageVo, String containerId, String hostIp, String userName) {
        DockerClient dockerClient = getDockerClient(hostIp);

        // 提交容器为镜像，这里的"new_image"和"new_tag"是新镜像的名字和标签
        CommitCmd commitCmd = dockerClient.commitCmd(containerId)
                .withRepository(imageVo.getName())
                .withTag(imageVo.getTagName())
                .withAuthor(userName)
                .withMessage(imageVo.getDescription());
        return commitCmd.exec();
    }

    public HashMap<String, String> pushImageToHorbor(ImageVo imageVo, String hostIp) {

        DockerClient dockerClient = getDockerClient(hostIp);
        //Harbor登录信息
        AuthConfig autoConfig = new AuthConfig().withRegistryAddress(harborUrl).withUsername(harborUser).withPassword(harborpassword);


        String localImageName = imageVo.getName() + ":" + imageVo.getTagName();
        String imageName = harborUrl + "/" + bucketName + "/" + imageVo.getName();

        //给镜像打上tag
        dockerClient.tagImageCmd(localImageName, imageName, imageVo.getTagName()).exec();
        //推送镜像至镜像仓库
        try {
            dockerClient.pushImageCmd(imageName).withAuthConfig(autoConfig).start().awaitCompletion();
            //push成功后，删除本地加载的镜像
            dockerClient.removeImageCmd(localImageName).exec();

            String totalImageName = imageName + ":" + imageVo.getTagName();
            InspectImageResponse exec = dockerClient.inspectImageCmd(totalImageName).exec();

            String size = String.format("%.1f GB", (float) exec.getSize() / 1073741824.0);

            HashMap<String, String> resultMap = new HashMap<>();
            resultMap.put("imageName",totalImageName);
            resultMap.put("size",size);

            return resultMap;
        } catch (InterruptedException e) {
            throw new RuntimeException("推送镜像失败:" + e);
        }

    }

    public void removeImage(String imageName, String hostIp){
        DockerClient dockerClient = getDockerClient(hostIp);
        dockerClient.removeImageCmd(imageName).withForce(true).exec();
    }
}