package com.zc.business.controller;

import com.ruoyi.common.utils.spring.SpringUtils;
import com.zc.business.domain.DcDevice;
import com.zc.business.service.IDcDeviceService;
import com.zc.business.service.impl.ExcelExportService;
import com.zc.business.service.impl.StatusService;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
import com.zc.business.domain.Status;

import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;
import java.util.stream.Collectors;

@Component
@EnableScheduling
public class DeviceStatus {
    @Autowired
    private IDcDeviceService deviceService;

    @Autowired
    private StatusService statusService;

    @Autowired
    private ExcelExportService excelExportService;


    //每天凌晨0点到晚上23点整点测试设备状态
    //  @Scheduled(cron = "0 0 0-23 * * ?")
    // @Scheduled(cron = "0 0 1,5,7,8,11,14,17,19,21,23")
    public void deviceStatus() {
        IDcDeviceService deviceService= SpringUtils.getBean(IDcDeviceService.class);
        StatusService statusService= SpringUtils.getBean(StatusService.class);
        ExecutorService executor = Executors.newFixedThreadPool(100);
        List<DcDevice> deviceList = deviceService.list();

        List<Future<Void>> futures = new ArrayList<>();

        for (DcDevice device : deviceList) {
            Callable<Void> task = () -> {
                try {
                    Status status = new Status();
                    InetAddress address = InetAddress.getByName(device.getDeviceIp());
                    String lostRate = getPingPacketLossRate(device.getDeviceIp());
                    boolean reachable = address.isReachable(5000); // Timeout: 5 seconds

                    status.setDeviceNo(device.getStakeMark());
                    status.setDeviceName(device.getDeviceName());
                    status.setDeviceIp(device.getDeviceIp());
                    LocalDateTime localDateTime = LocalDateTime.now();
                    status.setTime(localDateTime);
                    status.setLostRate(lostRate);

                    if (reachable) {
                        status.setDeviceStatus(1);
                        status.setSuccessRate("100.00%");
                    } else {
                        status.setDeviceStatus(0);
                        status.setSuccessRate("0.00%");
                    }

                    statusService.Add(status);
                } catch (IOException e) {
                    System.out.println("Error pinging " + device.getDeviceIp() + ": " + e.getMessage());
                }

                return null;
            };

            futures.add(executor.submit(task));
        }

        for (Future<Void> future : futures) {
            try {
                future.get();
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }

        executor.shutdown();
    }


    /**
     * 计算丢包率
     */
    public String getPingPacketLossRate(String ipAddress) {
        try {
            // Execute the ping command
            Process process = Runtime.getRuntime().exec("ping -c 4 " + ipAddress); // Sending 4 ICMP Echo Request packets

            // Read the output of the command
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            int packetsSent = 0;
            int packetsLost = 0;

            while ((line = reader.readLine()) != null) {
                // Check for lines containing packet loss information
                if (line.contains("packets transmitted")) {
                    // Extract the number of packets sent and lost
                    String[] stats = line.split(", ");
                    packetsSent = Integer.parseInt(stats[0].split(" ")[0]);
                    packetsLost = Integer.parseInt(stats[0].split(" ")[0]) - Integer.parseInt(stats[1].split(" ")[0]);
                }
            }

            // Calculate and return the packet loss rate
            if (packetsSent > 0) {
                return String.format("%.2f%%", (double) packetsLost / packetsSent * 100);
            } else {
                return "0.00%"; // No packets sent
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "-1.00%"; // Error occurred
        }
    }


    /**
     * 成功率和丢包率按小时分组
     * 每天17点 23点 30分导出excel表
     */

    //  @Scheduled(cron = "0 30 17,23 * * ?")
    public void calculateSuccessRate() {
        StatusService statusService = SpringUtils.getBean(StatusService.class);
        ExcelExportService excelExportService= SpringUtils.getBean(ExcelExportService.class);

        LocalDateTime todayStart = LocalDateTime.now().truncatedTo(ChronoUnit.DAYS);
        LocalDateTime currentTime = LocalDateTime.now();


        Status status = new Status();
        status.setStartTime(todayStart);
        status.setTime(currentTime);
        List<Status> listStatus = statusService.list(status);
        //根据时间分组
        Map<Integer, List<Status>> map = listStatus.stream()
                .collect(Collectors.groupingBy(Status -> Status.getTime().getHour()));
        //根据类型分组
        Map<String, List<Status>> maps = listStatus.stream().filter(iteam -> iteam.getType() != null).collect(Collectors.groupingBy(Status::getType));

        String filePath = CreateNamedExcel();
        excelExportService.exportDataToExcel(map, maps, filePath);
    }


    public String CreateNamedExcel() {
        LocalDateTime dateTime = LocalDateTime.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedDateTime = dateTime.format(formatter);
        //修改成服务器地址
        String filePath = "/home/excel/" + formattedDateTime + "--deviceStatus.xlsx";
        try (Workbook workbook = new XSSFWorkbook()) {
            FileOutputStream fileOut = new FileOutputStream(filePath);
            workbook.write(fileOut);
            System.out.println("Empty named Excel created successfully.");
        } catch (IOException e) {
            e.printStackTrace();
        }
        return filePath;
    }

}