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.*;
import com.mini.capi.biz.service.*;
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.model.info.TableTree;
import com.mini.capi.utils.*;
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
    private BizDbConfigService bizDbConfigService;

    @Resource
    private DataTableInfoService dataTableInfoService;

    @Resource
    private DataTableFieldService dataTableFieldService;

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


    private static final LoggerUtils logger = LoggerUtils.getInstance();

    /**
     * 主机在线状态检测
     */
    @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) {
                    logger.error(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());
        }
    }


    /**
     * 数据表同步
     */
    @GetMapping("getJobDataTableMarge")
    public ApiResult<?> getJobDataTableMarge() {
        List<BizDbConfig> configs = bizDbConfigService.list();
        List<CompletableFuture<Void>> futures = new ArrayList<>(configs.size());
        for (BizDbConfig config : configs) {
            CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
                try {
                    List<TableTree> tableTrees = MysqlUtils.getTableTrees(config);
                    for (TableTree tableTree : tableTrees) {
                        DataTableInfo tableInfo = tableTree.getTableInfo();
                        List<DataTableField> tableFields = tableTree.getTableFields();
                        for (DataTableField field : tableFields) {
                            dataTableFieldService.save(field);
                        }
                        dataTableInfoService.save(tableInfo);
                        logger.info("已同步数据库:", tableInfo.getDataSource(), ",数据表:", tableInfo.getTableName(), ",总计:", tableFields.size(), "个字段");
                    }
                } catch (Exception e) {
                    logger.error(e.getMessage());
                }
            }, hostMonitorExecutor); // 指定使用配置的线程池
            futures.add(future);
        }
        try {
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
                    .get(30, TimeUnit.SECONDS);
            return ApiResult.success();
        } catch (Exception e) {
            return ApiResult.error(101, e.getMessage());
        }
    }

    public void syncServerInfo(BizMonitorHost host) {
        try {
            // 查询账号，不存在直接返回
            QueryWrapper<BizMonitorAccount> accountQuery = new QueryWrapper<>();
            accountQuery.eq("host_id", host.getHostId()).eq("ssh_username", "ogsapp");
            BizMonitorAccount account = bizMonitorAccountService.getOne(accountQuery);
            if (account == null) return;
            // 获取服务器信息
            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);
            // 查询是否存在对应记录
            QueryWrapper<BizServerInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("host_id", host.getHostId());
            BizServerInfo serverInfo = bizServerInfoService.getOne(queryWrapper);
            bizServerInfoService.removeById(serverInfo.getId());
            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());
            serverInfo.setHostId(host.getHostId()); // 新对象初始化唯一标识
            bizServerInfoService.save(serverInfo);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }


    public void syncDeviceInfo(BizMonitorHost host, List<DiskInfo> diskInfos) {
        for (DiskInfo diskInfo : diskInfos) {
            QueryWrapper<BizDeviceInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("host_id", host.getHostId()).eq("device", diskInfo.getDevice()).eq("mount_point", diskInfo.getMountPoint());
            BizDeviceInfo deviceInfo = bizDeviceInfoService.getOne(queryWrapper);
            bizDeviceInfoService.removeById(deviceInfo.getId());
            deviceInfo.setDevice(diskInfo.getDevice());
            deviceInfo.setMountPoint(diskInfo.getMountPoint());
            deviceInfo.setTotalSize(diskInfo.getTotalSize());
            deviceInfo.setUsedSize(diskInfo.getUsedSize());
            deviceInfo.setUsageRate(diskInfo.getUsageRate());
            deviceInfo.setLastOnlineTime(LocalDateTime.now());
            deviceInfo.setHostId(host.getHostId());
            bizDeviceInfoService.save(deviceInfo);
        }
    }
}
