package com.qqchen.deploy.backend.framework.ssh.impl;

import com.qqchen.deploy.backend.framework.dto.CommandResult;
import com.qqchen.deploy.backend.framework.dto.DiskInfo;
import com.qqchen.deploy.backend.framework.dto.DiskUsageInfo;
import com.qqchen.deploy.backend.framework.dto.MonitorData;
import com.qqchen.deploy.backend.framework.enums.OsTypeEnum;
import com.qqchen.deploy.backend.framework.ssh.AbstractSSHCommandService;
import lombok.extern.slf4j.Slf4j;
import net.schmizz.sshj.SSHClient;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;

/**
 * MacOS SSH命令服务实现（Framework层）
 */
@Slf4j
@Service
public class MacOSSSHCommandServiceImpl extends AbstractSSHCommandService {
    
    // ==================== 命令常量 ====================
    
    /**
     * CPU使用率命令
     */
    private static final String CMD_CPU_USAGE = 
        "top -l 1 -s 0 | grep 'CPU usage' | awk '{print $3}' | sed 's/%//'";
    
    /**
     * 内存使用率命令
     */
    private static final String CMD_MEMORY_USAGE = 
        "vm_stat | awk '/Pages active/ {active=$3} /Pages wired/ {wired=$4} /Pages free/ {free=$3} END {used=active+wired; total=used+free; printf \"%.2f\", (used/total)*100}'";
    
    /**
     * 磁盘使用率命令（格式：设备|挂载点|容量|已用|可用|使用率）
     */
    private static final String CMD_DISK_USAGE = 
        "df -h | grep -E '^/dev/disk' | awk '{print $1 \"|\" $9 \"|\" $2 \"|\" $3 \"|\" $4 \"|\" $5}' | sed 's/Gi//g; s/%//'";
    
    /**
     * 网络接收流量命令(KB/s) - 使用netstat统计
     */
    private static final String CMD_NETWORK_RX = 
        "netstat -ib | awk '/en[0-9]/ && !/Link/ {sum+=$7} END {print int(sum/1024)}'";
    
    /**
     * 网络发送流量命令(KB/s) - 使用netstat统计
     */
    private static final String CMD_NETWORK_TX = 
        "netstat -ib | awk '/en[0-9]/ && !/Link/ {sum+=$10} END {print int(sum/1024)}'";
    
    // ==================== 实现方法 ====================
    
    @Override
    public String getHostname(SSHClient sshClient) {
        return safeExecute(sshClient, "hostname");
    }
    
    @Override
    public String getOsVersion(SSHClient sshClient) {
        // 获取MacOS版本信息
        String command = "sw_vers -productName && sw_vers -productVersion";
        return safeExecute(sshClient, command);
    }
    
    @Override
    public Integer getCpuCores(SSHClient sshClient) {
        // 使用sysctl获取CPU核心数
        String result = safeExecute(sshClient, "sysctl -n hw.ncpu");
        return parseInteger(result);
    }
    
    @Override
    public Integer getMemorySize(SSHClient sshClient) {
        // 获取内存大小（GB）
        String command = "sysctl -n hw.memsize | awk '{print int($1/1024/1024/1024)}'";
        String result = safeExecute(sshClient, command);
        return parseInteger(result);
    }
    
    @Override
    public List<DiskInfo> getDiskInfo(SSHClient sshClient) {
        // 使用df命令获取所有挂载点的磁盘信息
        // 格式: 设备|挂载点|总大小(GB)
        // MacOS的df输出格式: Filesystem 512-blocks Used Available Capacity iused ifree %iused Mounted
        String command = "df -g | grep -E '^/dev/disk' | awk '{print $1 \"| \" $9 \"| \" $2}'";
        String result = safeExecute(sshClient, command);
        
        List<DiskInfo> diskList = new ArrayList<>();
        Set<String> seenDevices = new HashSet<>();
        
        if (result != null && !result.trim().isEmpty()) {
            String[] lines = result.trim().split("\\n");
            for (String line : lines) {
                String[] parts = line.split("\\|");
                if (parts.length >= 3) {
                    try {
                        String device = parts[0].trim();
                        String mountPoint = parts[1].trim();
                        String sizeStr = parts[2].trim();
                        
                        // 去重
                        if (seenDevices.contains(device)) {
                            log.debug("跳过重复设备: {} -> {}", device, mountPoint);
                            continue;
                        }
                        seenDevices.add(device);
                        
                        // MacOS通常使用APFS，但我们从设备名简化处理
                        String fileSystem = device.contains("disk") ? "APFS" : "HFS+";
                        
                        DiskInfo diskInfo = DiskInfo.builder()
                            .mountPoint(mountPoint)
                            .fileSystem(fileSystem)
                            .totalSize(new BigDecimal(sizeStr))
                            .build();
                        diskList.add(diskInfo);
                    } catch (NumberFormatException e) {
                        log.warn("解析磁盘信息失败: {}", line, e);
                    }
                }
            }
        }
        return diskList;
    }
    
    @Override
    public BigDecimal getCpuUsage(SSHClient sshClient) {
        String result = safeExecute(sshClient, CMD_CPU_USAGE);
        return parseBigDecimal(result);
    }
    
    @Override
    public BigDecimal getMemoryUsage(SSHClient sshClient) {
        String result = safeExecute(sshClient, CMD_MEMORY_USAGE);
        return parseBigDecimal(result);
    }
    
    @Override
    public List<DiskUsageInfo> getDiskUsage(SSHClient sshClient) {
        String result = safeExecute(sshClient, CMD_DISK_USAGE);
        
        List<DiskUsageInfo> diskUsageList = new ArrayList<>();
        Set<String> seenDevices = new HashSet<>();
        
        if (result != null && !result.trim().isEmpty()) {
            String[] lines = result.trim().split("\\n");
            for (String line : lines) {
                String[] parts = line.split("\\|");
                if (parts.length >= 6) {
                    try {
                        String device = parts[0].trim();
                        String mountPoint = parts[1].trim();
                        String totalStr = parts[2].trim();
                        String usedStr = parts[3].trim();
                        String usageStr = parts[5].trim();
                        
                        // 去重
                        if (seenDevices.contains(device)) {
                            continue;
                        }
                        seenDevices.add(device);
                        
                        // 简化的文件系统类型
                        String fileSystem = "APFS";
                        
                        DiskUsageInfo diskUsage = DiskUsageInfo.builder()
                            .mountPoint(mountPoint)
                            .fileSystem(fileSystem)
                            .totalSize(parseBigDecimal(totalStr))
                            .usedSize(parseBigDecimal(usedStr))
                            .usagePercent(parseBigDecimal(usageStr))
                            .build();
                        diskUsageList.add(diskUsage);
                    } catch (Exception e) {
                        log.warn("解析MacOS磁盘使用率失败: {}", line, e);
                    }
                }
            }
        }
        return diskUsageList;
    }
    
    @Override
    public Long getNetworkRx(SSHClient sshClient) {
        String result = safeExecute(sshClient, CMD_NETWORK_RX);
        return parseLong(result);
    }
    
    @Override
    public Long getNetworkTx(SSHClient sshClient) {
        String result = safeExecute(sshClient, CMD_NETWORK_TX);
        return parseLong(result);
    }
    
    /**
     * 解析 Long 类型结果
     */
    private Long parseLong(String result) {
        if (result == null || result.trim().isEmpty()) {
            return null;
        }
        try {
            return Long.parseLong(result.trim());
        } catch (NumberFormatException e) {
            log.warn("解析Long失败: {}", result, e);
            return null;
        }
    }
    
    @Override
    public MonitorData collectMonitorData(SSHClient sshClient) {
        try {
            // 1. 准备5个监控命令（使用统一的命令常量 ✅）
            List<String> commands = Arrays.asList(
                CMD_CPU_USAGE,
                CMD_MEMORY_USAGE,
                CMD_DISK_USAGE,
                CMD_NETWORK_RX,
                CMD_NETWORK_TX
            );
            
            // 2. 批量执行命令（只需1次网络往返 ✅）
            List<CommandResult> results = executeCommands(sshClient, commands);
            
            // 3. 解析结果
            BigDecimal cpuUsage = parseCommandResultToBigDecimal(results.get(0));
            BigDecimal memoryUsage = parseCommandResultToBigDecimal(results.get(1));
            List<DiskUsageInfo> diskUsage = parseDiskUsageFromCommand(results.get(2));
            Long networkRx = parseCommandResultToLong(results.get(3));
            Long networkTx = parseCommandResultToLong(results.get(4));
            
            // 4. 构建监控数据
            return MonitorData.builder()
                .cpuUsage(cpuUsage)
                .memoryUsage(memoryUsage)
                .diskUsage(diskUsage)
                .networkRx(networkRx)
                .networkTx(networkTx)
                .build();
                
        } catch (Exception e) {
            log.error("批量采集macOS监控数据失败", e);
            return null;
        }
    }
    
    /**
     * 从CommandResult解析BigDecimal
     */
    private BigDecimal parseCommandResultToBigDecimal(CommandResult result) {
        if (result == null || !result.isSuccess() || result.getOutput() == null || result.getOutput().trim().isEmpty()) {
            return null;
        }
        return parseBigDecimal(result.getOutput());
    }
    
    /**
     * 从CommandResult解析Long
     */
    private Long parseCommandResultToLong(CommandResult result) {
        if (result == null || !result.isSuccess() || result.getOutput() == null || result.getOutput().trim().isEmpty()) {
            return null;
        }
        return parseLong(result.getOutput());
    }
    
    /**
     * 从CommandResult解析macOS磁盘使用率（格式：设备|挂载点|容量|已用|可用|使用率）
     */
    private List<DiskUsageInfo> parseDiskUsageFromCommand(CommandResult result) {
        List<DiskUsageInfo> diskUsageList = new ArrayList<>();
        
        if (result == null || !result.isSuccess() || result.getOutput() == null || result.getOutput().trim().isEmpty()) {
            return diskUsageList;
        }
        
        Set<String> seenDevices = new HashSet<>();
        String[] lines = result.getOutput().trim().split("\\n");
        
        for (String line : lines) {
            String[] parts = line.split("\\|");
            if (parts.length >= 6) {
                try {
                    String device = parts[0].trim();
                    String mountPoint = parts[1].trim();
                    String totalStr = parts[2].trim();
                    String usedStr = parts[3].trim();
                    String usageStr = parts[5].trim();
                    
                    // 去重
                    if (seenDevices.contains(device)) {
                        continue;
                    }
                    seenDevices.add(device);
                    
                    // 简化的文件系统类型
                    String fileSystem = "APFS";
                    
                    DiskUsageInfo diskUsage = DiskUsageInfo.builder()
                        .mountPoint(mountPoint)
                        .fileSystem(fileSystem)
                        .totalSize(parseBigDecimal(totalStr))
                        .usedSize(parseBigDecimal(usedStr))
                        .usagePercent(parseBigDecimal(usageStr))
                        .build();
                    diskUsageList.add(diskUsage);
                } catch (Exception e) {
                    log.warn("解析macOS磁盘使用率失败: {}", line, e);
                }
            }
        }
        
        return diskUsageList;
    }
    
    @Override
    public OsTypeEnum getSupportedOsType() {
        return OsTypeEnum.MACOS;
    }
}
