package devops;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import cn.reghao.bnt.common.docker.DockerImpl;
import cn.reghao.bnt.common.docker.model.Config;
import cn.reghao.bnt.common.docker.model.Volumes;
import cn.reghao.jutil.jdk.serializer.JsonConverter;
import cn.reghao.jutil.jdk.shell.ShellExecutor;
import cn.reghao.jutil.jdk.shell.ShellResult;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2022-05-07 09:32:40
 */
@Slf4j
public class DockerTest {
    void setLogLevel() {
        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
        Logger rootLogger = loggerContext.getLogger("ROOT");
        rootLogger.setLevel(Level.INFO);
    }

    @Test
    public void dockerBuildTest() throws Exception {
        setLogLevel();
        DockerImpl docker = new DockerImpl();
        /*String repoTag = "file:12345678";
        String compileHome = "/home/reghao/code/aha/tnb/file/file-service";
        docker.build(repoTag, compileHome);*/

        String image = "node:16.20.2-buster-slim";
        String sourceCodeDir = "/home/reghao/Downloads/0/tnbapp";
        sourceCodeDir = "/home/reghao/Downloads/0/iquizoo.admin/";
        String nodeModulesDir = "/home/reghao/Downloads/0/node_modules";
        String buildCmd = "npm run build";
        String buildCmd1 = "npm i && npm run build";
        String buildCmd2 = "npm run test";
        String buildCmd3 = "cd /app && npm --registry http://registry.npm.taobao.org i && npm run uat";
        String buildCmd4 = "npm --registry http://registry.npm.taobao.org i";

        Config config = new Config(image);
        config.setVolumes(new Volumes());
        config.setCmd(List.of("sh", "-c", buildCmd3));

        Map<String, String> map = config.getVolumes().getMap();
        map.put("/node_modules", nodeModulesDir);
        map.put("/app", sourceCodeDir);

        long start = 0;
        start = System.currentTimeMillis();
        docker.runAndRm(config);
        log.info("cost {} ms", System.currentTimeMillis()-start);

        /*config.setCmd(List.of("sh", "-c", "cd /front && " + buildCmd1));
        start = System.currentTimeMillis();
        docker.runAndRm(config);
        log.info("cost {} ms", System.currentTimeMillis()-start);*/
    }

    /**
     * 解析 docker 容器启动参数
     *
     * @param
     * @return
     * @date 2025-07-04 15:51:09
     */
    @Test
    public void parseContainerArgsTest() {
        String image = "node:16.20.2-buster-slim";
        Config config = new Config(image);
        config.setVolumes(new Volumes());
        config.getHostConfig().setInit(true);

        String json = JsonConverter.objectToJson(config);
        System.out.println(json);

        String json1 = "{ \"Env\":[\"ASPNETCORE_ENVIRONMENT=Production\", \"ASPNETCORE_URLS=http://172.16.45.67:8015;https://172.16.45.67:8115\"], \"HostConfig\":{\"Init\":true}}";
        Config config1 = JsonConverter.jsonToObject(json1, Config.class);
        System.out.println();
    }

    @Test
    public void dockerConfigTest() {
        Config config = new Config();

        Volumes volumes = new Volumes();
        volumes.getMap().put("/app1", "/app1");
        volumes.getMap().put("/app2", "/app2");
        config.setVolumes(volumes);

        System.out.println(JsonConverter.objectToJson(config));
    }

    @Test
    public void linuxPackageTest() {
        ShellExecutor shell = new ShellExecutor();
        String versionCmd = "/usr/bin/pacman -Q";

        List<String> pkgList = new ArrayList<>();
        ShellResult shellResult = shell.exec(versionCmd.split("\\s+"));
        if (shellResult.getExitCode() == 0) {
            for (String line : shellResult.getResult().split(System.lineSeparator())) {
                String[] arr = line.split("\\s+");
                pkgList.add(arr[0]);
            }
        }

        Map<String, LinuxPkg> linuxPkgMap = new HashMap<>();
        for (int i = 0; i < pkgList.size(); i++) {
            String pkg = pkgList.get(i);
            versionCmd = "/usr/bin/pacman -Qi " + pkg;
            shellResult = shell.exec(versionCmd.split("\\s+"));

            Map<String, String> map = new HashMap<>();
            if (shellResult.getExitCode() == 0) {
                for (String line : shellResult.getResult().split(System.lineSeparator())) {
                    if (line.startsWith("Optional Deps")) {
                        continue;
                    }

                    String[] arr = line.split(": ");
                    try {
                        map.put(StringUtils.trimAllWhitespace(arr[0]), arr[1]);
                    } catch (Exception e) {
                        //e.printStackTrace();
                    }
                }
            }

            int id = linuxPkgMap.size()+1;
            String name = map.get("Name");
            LinuxPkg linuxPkg = linuxPkgMap.computeIfAbsent(name, v -> new LinuxPkg(id, name));
            String dependsOn = map.get("DependsOn");
            if (!dependsOn.equals("None")) {
                for (String line : dependsOn.split(" ")) {
                    String pkgName = StringUtils.trimAllWhitespace(line);
                    if (!pkgName.isBlank()) {
                        for (String key : pkgList) {
                            if (pkgName.startsWith(key)) {
                                int id1 = linuxPkgMap.size()+1;
                                LinuxPkg linuxPkg1 = linuxPkgMap.computeIfAbsent(key, v -> new LinuxPkg(id1, key));
                            }
                        }
                    }
                }
            }

            String requiredBy = map.get("RequiredBy");
            if (!requiredBy.equals("None")) {
                for (String line : requiredBy.split(" ")) {
                    String pkgName = StringUtils.trimAllWhitespace(line);
                    if (!pkgName.isBlank()) {
                        for (String key : pkgList) {
                            int id1 = linuxPkgMap.size()+1;
                            if (pkgName.equals(key)) {
                                LinuxPkg linuxPkg1 = linuxPkgMap.computeIfAbsent(key, v -> new LinuxPkg(id1, key));
                                linuxPkg.getChildren().add(key);
                            } else if (pkgName.startsWith(key)) {
                                LinuxPkg linuxPkg1 = linuxPkgMap.computeIfAbsent(key, v -> new LinuxPkg(id1, key));
                                linuxPkg.getChildren().add(key);
                            }
                        }
                    }
                }
            }

            System.out.printf("%s: %s\n", i, pkg);
        }

        linuxPkgMap.forEach((name, value) -> {
            for (String child : value.getChildren()) {
                linuxPkgMap.get(child).setPid(value.getId());
            }
        });

        Map<Integer, List<LinuxPkg>> groupMap = linuxPkgMap.values().stream()
                .collect(Collectors.groupingBy(LinuxPkg::getPid));
        System.out.println();
    }

    @NoArgsConstructor
    @Setter
    @Getter
    static class LinuxPkg {
        private int id;
        private int pid;
        private String name;
        private Set<String> children = new HashSet<>();

        public LinuxPkg(int id, String name) {
            this.id = id;
            this.name = name;
        }
    }
}
