package com.mini.capi.utils;


import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.mini.capi.model.info.CpuInfo;
import com.mini.capi.model.info.DiskInfo;
import com.mini.capi.model.info.ServerInfo;
import lombok.Data;
import org.springframework.util.StringUtils;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;


public class SystemInfoUtil {


    // SSH 连接超时时间（毫秒）
    private static final int SSH_TIMEOUT = 5000;


    /**
     * 建立SSH连接
     */
    private static Session getSshSession(String host, int port, String username, String password) throws Exception {
        JSch jsch = new JSch();
        Session session = jsch.getSession(username, host, port);
        session.setPassword(password);

        Properties config = new Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);

        session.setTimeout(SSH_TIMEOUT);
        session.connect();
        return session;
    }

    /**
     * 执行SSH命令并返回结果
     */
    private static String executeCommand(Session session, String command) throws Exception {
        ChannelExec channel = (ChannelExec) session.openChannel("exec");
        channel.setCommand(command);

        InputStream in = channel.getInputStream();
        channel.connect();

        BufferedReader reader = new BufferedReader(
                new InputStreamReader(in, StandardCharsets.UTF_8)
        );
        StringBuilder result = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            result.append(line).append("\n");
        }

        reader.close();
        channel.disconnect();
        return result.toString().trim();
    }


    /**
     * 获取服务器基础信息
     */
    public static ServerInfo getServerBasicInfo(String host, int port, String username, String password, String ipAddress) throws Exception {
        ServerInfo info = new ServerInfo();
        Session session = null;
        try {
            session = getSshSession(host, port, username, password);

            // 主机运行时间
            String uptimeResult = executeCommand(session, "uptime");
            if (StringUtils.hasText(uptimeResult)) {
                String[] parts = uptimeResult.split("up ");
                if (parts.length > 1) {
                    info.setUptime(parts[1].split(",  ")[0]);
                }
            }

            // 操作系统
            String osResult = executeCommand(session, "cat /etc/os-release | grep PRETTY_NAME | cut -d'=' -f2 | tr -d '\"'");
            info.setOs(osResult.isEmpty() ? "Unknown" : osResult);

            // 内核版本
            info.setKernelVersion(executeCommand(session, "uname -r"));

            // 主机名
            info.setHostname(executeCommand(session, "hostname"));

            // IP地址（传入参数）
            info.setIpAddress(ipAddress);

            // CPU型号
            String cpuResult = executeCommand(session, "cat /proc/cpuinfo | grep 'model name' | head -n 1 | cut -d: -f2 | sed -e 's/^ *//'");
            info.setCpuModel(cpuResult.isEmpty() ? "Unknown" : cpuResult);

            // 内存总量
            String memResult = executeCommand(session, "free -h | grep Mem | awk '{print $2}'");
            info.setMemoryTotal(memResult.isEmpty() ? "Unknown" : memResult);

        } finally {
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
        return info;
    }

    /**
     * 获取CPU和内存使用率
     */
    public static CpuInfo getCpuMemUsage(String host, int port, String username, String password) throws Exception {
        CpuInfo usage = new CpuInfo();
        Session session = null;
        try {
            session = getSshSession(host, port, username, password);

            // CPU使用率
            String cpuCommand = "top -bn2 | grep '%Cpu' | tail -n1 | awk '{print 100 - $8}'";
            String cpuResult = executeCommand(session, cpuCommand);
            if (StringUtils.hasText(cpuResult)) {
                usage.setCpuUsage(Double.parseDouble(cpuResult));
            }
            // 内存使用率
            String memCommand = "free | grep Mem | awk '{print $3/$2 * 100}'";
            String memResult = executeCommand(session, memCommand);
            if (StringUtils.hasText(memResult)) {
                usage.setMemoryUsage(Double.parseDouble(memResult));
            }

        } finally {
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
        return usage;
    }

    /**
     * 获取所有磁盘信息
     */
    public static List<DiskInfo> getDiskInfos(String host, int port, String username, String password) throws Exception {
        List<DiskInfo> diskInfos = new ArrayList<>();
        Session session = null;
        try {
            session = getSshSession(host, port, username, password);
            // 关键修改：强制英文输出 + 调整字段索引
            String diskCommand = "LANG=en_US.UTF-8 df -h | awk '{print $1, $6, $2, $3, $5}'";
            String diskResult = executeCommand(session, diskCommand);

            if (StringUtils.hasText(diskResult)) {
                String[] lines = diskResult.split("\n");
                for (String line : lines) {
                    // 过滤空行和标题行
                    if (line.trim().isEmpty() || line.contains("Filesystem")) {
                        continue;
                    }
                    // 按任意空格分割（兼容多个空格）
                    String[] parts = line.trim().split("\\s+");
                    if (parts.length >= 5) {
                        String usageStr = parts[4].replace("%", "").trim();
                        DiskInfo diskInfo = new DiskInfo(parts[0], parts[1], parts[2], parts[3], Double.parseDouble(usageStr));
                        diskInfos.add(diskInfo);
                    }
                }
            }

        } finally {
            if (session != null && session.isConnected()) {
                session.disconnect();
            }
        }
        return diskInfos;
    }

}
