package com.css.simulation.resource.monitor.infra.scheduler;

import api.common.pojo.dto.Host;
import api.common.pojo.po.home.SystemServerPO;
import api.common.util.SshUtil;
import api.common.util.StringUtil;
import api.common.util.TimeUtil;
import com.css.simulation.resource.monitor.infra.minio.MinioConfiguration;
import com.css.simulation.resource.monitor.domain.SystemServerDomainService;
import com.css.simulation.resource.monitor.infra.mysql.mapper.ScenePackageSublistMapper;
import com.css.simulation.resource.monitor.infra.mysql.entity.GeneralEntity;
import com.css.simulation.resource.monitor.infra.util.MinioUtil;
import io.minio.MinioClient;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.session.ClientSession;
import org.dom4j.DocumentException;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Component
@Data
@Slf4j
@ConfigurationProperties(prefix = "ssh")
public class ServerScheduler {

    List<Host> hostList;


    @Resource
    private SystemServerDomainService systemServerDomainService;
    @Resource
    private ScenePackageSublistMapper scenePackageSublistMapper;
    @Resource
    private MinioClient minioClient;
    @Resource
    private MinioConfiguration minioConfiguration;


    @Scheduled(fixedDelay = 60 * 1000)
    public void server() {
        try {
            List<SystemServerPO> systemServerPOList = new ArrayList<>();
            log.info("服务器列表为：" + hostList);
            for (Host host : hostList) {
                int taskNumber = 0;
                SshClient sshClient = SshClient.setUpDefaultClient();
                String ip = host.getHostname();
                String username = host.getUsername();
                String password = host.getPassword();
                String type = host.getType();
                ClientSession session = SshUtil.getSession(sshClient, ip, username, password);
                double gpuUsage = 0.0;
                long gpuTotal = 0L;
                if ("gpu".equals(type)) {
                    gpuUsage = SshUtil.gpuUsage(session);
                    gpuTotal = SshUtil.gpuTotal(session);
                    String podList = SshUtil.execute(session, "kubectl get pod | grep project");
                    taskNumber = StringUtil.countSubString(podList, "project");
                }

                SystemServerPO systemServerPO = SystemServerPO.builder()
                        .id(StringUtil.getRandomUUID())
                        .serverId(SshUtil.hostname(session))
                        .serverAddress(ip)
                        .serverType(type)
                        .memoryUsage(SshUtil.memoryUsage(session))
                        .memoryAvailable(SshUtil.memoryAvailable(session))
                        .memoryTotal(SshUtil.memoryTotal(session))
                        .diskUsage(SshUtil.diskUsage(session))
                        .diskAvailable(SshUtil.diskAvailable(session))
                        .diskTotal(SshUtil.diskTotal(session))
                        .cpuUsage(SshUtil.cpuUsage(session))
                        .cpuTotal(SshUtil.cpuTotal(session))
                        .gpuUsage(gpuUsage)
                        .gpuTotal(gpuTotal)
                        .taskNumber(taskNumber)
                        .build();
                systemServerPO.setCreateTime(TimeUtil.getNowForMysql());
                systemServerPO.setCreateUserId("simulation-resource-monitor");
                systemServerPO.setModifyTime(TimeUtil.getNowForMysql());
                systemServerPO.setModifyUserId("simulation-resource-monitor");
                systemServerPO.setModifyTime(TimeUtil.getNowForMysql());
                systemServerPO.setIsDeleted("0");
                systemServerPOList.add(systemServerPO);
                session.close();
                sshClient.stop();
            }
            log.info("获取服务器信息。" + systemServerPOList);
            systemServerDomainService.deleteAndInsert(systemServerPOList);
        } catch (IOException | DocumentException | InterruptedException e) {
            throw new RuntimeException(e);
        }

    }


    @Scheduled(fixedDelay = 24 * 60 * 60 * 1000)
    public void deleteGeneral() {
        log.info("开始清除泛化垃圾文件。");
        try {
            //1 查询泛化场景测试包包括的所有泛化场景id序列（保留已删除的测试包）
            List<String> sceneGeneralizationIdsList = scenePackageSublistMapper.selectSceneGeneralizationIds();
            //2 将所有序列拆开
            List<String> sceneGeneralizationIdList = new ArrayList<>();
            sceneGeneralizationIdsList.forEach(ids -> {
                String[] split = ids.split(",");
                sceneGeneralizationIdList.addAll(Arrays.asList(split));
            });
            //3 查询不在id列表中的所有泛化数据
            List<GeneralEntity> generalEntities = scenePackageSublistMapper.selectGeneralDataNotIn(sceneGeneralizationIdList);
            log.info("准备删除：" + generalEntities);
            generalEntities.forEach(
                    generalEntity -> {
                        if (StringUtil.isNotEmpty(generalEntity.getOsgbAddress())) {
                            MinioUtil.rm(minioClient, minioConfiguration.getBucketName(), generalEntity.getOsgbAddress());
                        }
                        if (StringUtil.isNotEmpty(generalEntity.getXodrAddress())) {
                            MinioUtil.rm(minioClient, minioConfiguration.getBucketName(), generalEntity.getXodrAddress());
                        }
                        if (StringUtil.isNotEmpty(generalEntity.getXoscAddress())) {
                            MinioUtil.rm(minioClient, minioConfiguration.getBucketName(), generalEntity.getXoscAddress());
                        }
                        scenePackageSublistMapper.deleteById(generalEntity.getId());
                    }
            );
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

    }

}
