package com.mini.capi.api.job;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mini.capi.biz.domain.BizDeviceInfo;
import com.mini.capi.biz.domain.BizMonitorAccount;
import com.mini.capi.biz.domain.BizMonitorHost;
import com.mini.capi.biz.domain.BizServerInfo;
import com.mini.capi.biz.service.BizDeviceInfoService;
import com.mini.capi.biz.service.BizMonitorAccountService;
import com.mini.capi.biz.service.BizMonitorHostService;
import com.mini.capi.biz.service.BizServerInfoService;
import com.mini.capi.model.ApiResult;
import com.mini.capi.model.info.CpuInfo;
import com.mini.capi.model.info.DiskInfo;
import com.mini.capi.model.info.ServerInfo;
import com.mini.capi.utils.NetworkUtils;
import com.mini.capi.utils.SystemInfoUtil;
import com.mini.capi.utils.vId;
import jakarta.annotation.Resource;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/jobApi")
public class jobController {


    @Resource
    private BizMonitorHostService bizMonitorHostService;


    @Resource
    private BizMonitorAccountService bizMonitorAccountService;

    @Resource
    private BizServerInfoService bizServerInfoService;

    @Resource
    private BizDeviceInfoService bizDeviceInfoService;

    // 注入配置好的线程池
    @Resource(name = "hostMonitorExecutor")
    private ThreadPoolTaskExecutor hostMonitorExecutor;

    /**
     * 主机在线状态检测
     */
    @GetMapping("getMonitHostStatus")
    public ApiResult<?> getJobMonitHostStatus() {
        List<BizMonitorHost> monitorHosts = bizMonitorHostService.list();
        List<CompletableFuture<Void>> futures = new ArrayList<>(monitorHosts.size());
        for (BizMonitorHost monitorHost : monitorHosts) {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                try {
                    UpdateWrapper<BizMonitorHost> updateWrapper = new UpdateWrapper<>();
                    updateWrapper.eq("host_id", monitorHost.getHostId());
                    boolean isReachable = NetworkUtils.isNetworkReachable(monitorHost.getIpAddress());
                    monitorHost.setUstatus(isReachable ? "1" : "0");
                    if (isReachable) {
                        syncServerInfo(monitorHost);
                        monitorHost.setLastOnlineTime(LocalDateTime.now());
                    }
                    bizMonitorHostService.update(monitorHost, updateWrapper);
                } catch (Exception e) {
                    System.out.println(e.getMessage());
                }
            }, hostMonitorExecutor); // 指定使用配置的线程池
            futures.add(future);
        }
        try {
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                    .get(60, TimeUnit.SECONDS); // 超时时间可根据业务调整
            return ApiResult.success();
        } catch (Exception e) {
            return ApiResult.error(101, e.getMessage());
        }
    }


    public void syncServerInfo(BizMonitorHost host) {
        try {
            QueryWrapper<BizMonitorAccount> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("host_id", host.getHostId()).eq("ssh_username", "ogsapp");
            BizMonitorAccount account = bizMonitorAccountService.getOne(queryWrapper);
            if (account != null) {
                CpuInfo cpuInfo = SystemInfoUtil.getCpuMemUsage(host.getIpAddress(), account.getSshPort(), account.getSshUsername(), account.getSshPassword());
                ServerInfo info = SystemInfoUtil.getServerBasicInfo(host.getIpAddress(), account.getSshPort(), account.getSshUsername(), account.getSshPassword(), host.getIpAddress());
                List<DiskInfo> diskInfos = SystemInfoUtil.getDiskInfos(host.getIpAddress(), account.getSshPort(), account.getSshUsername(), account.getSshPassword());
                syncDeviceInfo(host, diskInfos);
                Optional<BizServerInfo> serverInfoOpt = Optional.ofNullable(
                        bizServerInfoService.getOne(new QueryWrapper<BizServerInfo>().eq("host_id", host.getHostId()))
                );
                BizServerInfo serverInfo = serverInfoOpt.orElseGet(() -> {
                    BizServerInfo newInfo = new BizServerInfo();
                    newInfo.setHostId(host.getHostId()); // 初始化唯一标识
                    return newInfo;
                });
                serverInfo.setUptime(info.getUptime());
                serverInfo.setOs(info.getOs());
                serverInfo.setKernelVersion(info.getKernelVersion());
                serverInfo.setHostname(info.getHostname());
                serverInfo.setIpAddress(info.getIpAddress());
                serverInfo.setCpuModel(info.getCpuModel());
                serverInfo.setMemoryTotal(info.getMemoryTotal());

                serverInfo.setCpuUsage(cpuInfo.getCpuUsage());
                serverInfo.setMemoryUsage(cpuInfo.getMemoryUsage());
                serverInfo.setLastOnlineTime(LocalDateTime.now());

                UpdateWrapper<BizServerInfo> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("host_id", host.getHostId());
                bizServerInfoService.saveOrUpdate(serverInfo, updateWrapper);
            }
        } catch (Exception e) {
            System.out.print(e.getMessage());
        }
    }


    public void syncDeviceInfo(BizMonitorHost host, List<DiskInfo> diskInfos) {
        for (DiskInfo diskInfo : diskInfos) {
            Optional<BizDeviceInfo> deviceInfoOpt = Optional.ofNullable(
                    bizDeviceInfoService.getOne(new QueryWrapper<BizDeviceInfo>().eq("host_id", host.getHostId()).eq("device", diskInfo.getDevice()).eq("mount_point", diskInfo.getMountPoint()))
            );
            BizDeviceInfo deviceInfo = deviceInfoOpt.orElseGet(() -> {
                BizDeviceInfo newInfo = new BizDeviceInfo();
                newInfo.setHostId(host.getHostId()); // 初始化唯一标识
                return newInfo;
            });
            deviceInfo.setDevice(diskInfo.getDevice());
            deviceInfo.setMountPoint(diskInfo.getMountPoint());
            deviceInfo.setTotalSize(diskInfo.getTotalSize());
            deviceInfo.setUsedSize(diskInfo.getUsedSize());
            deviceInfo.setUsageRate(diskInfo.getUsageRate());
            deviceInfo.setLastOnlineTime(LocalDateTime.now());

            UpdateWrapper<BizDeviceInfo> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("host_id", host.getHostId()).eq("device", diskInfo.getDevice()).eq("mount_point", diskInfo.getMountPoint());
            bizDeviceInfoService.saveOrUpdate(deviceInfo, updateWrapper);
        }
    }
}
