package com.skr.mdm.task;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.google.common.collect.Lists;
import com.skr.mdm.constant.UserOnlineConstants;
import com.skr.mdm.dao.DeviceEquipmentDao;
import com.skr.mdm.dao.LogUserOnlineDao;
import com.skr.mdm.enums.EquipmentStateEnum;
import com.skr.mdm.entity.DeviceEquipmentDO;
import com.skr.mdm.entity.LogUserOnlineDO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;

/**
 * http心跳离线检测
 *
 * @author nfq
 * @date 2020/9/14 11:07
 */
@Component
@EnableScheduling
@EnableAsync
@Slf4j
public class HeartbeatTimeTask {

    @Autowired
    private DeviceEquipmentDao equipmentDao;
    @Autowired
    private LogUserOnlineDao logUserOnlineDao;

    public HeartbeatTimeTask() {
    }

    @Async
    @Scheduled(fixedRate = UserOnlineConstants.HEARTBEAT_CHECK_MS)
    public void heartbeatCheck() {
        TimeInterval timer = DateUtil.timer();
        // 查询http在线的设备
        List<DeviceEquipmentDO> equipmentDOList = new LambdaQueryChainWrapper<>(equipmentDao)
                .isNotNull(DeviceEquipmentDO::getHeartbeatTime)
                .eq(DeviceEquipmentDO::getEquipmentState, EquipmentStateEnum.HTTP_ONLINE.getState())
                .list();
        if (CollectionUtils.isNotEmpty(equipmentDOList)) {
            List<Integer> offlineEquipmentIdList = Lists.newArrayListWithExpectedSize(equipmentDOList.size());
            List<LogUserOnlineDO> logUserOnlineDOList = Lists.newArrayListWithExpectedSize(equipmentDOList.size());
            equipmentDOList.forEach(equipmentDO -> {
                long heartbeatTime = equipmentDO.getHeartbeatTime().getTime();
                long time = System.currentTimeMillis() - heartbeatTime;
                if (time > UserOnlineConstants.OFFLINE_MS) {
                    // 离线
                    offlineEquipmentIdList.add(equipmentDO.getId());
                    // 添加离线日志
                    LogUserOnlineDO logUserOnlineDO = LogUserOnlineDO.builder()
                            .equipmentId(equipmentDO.getId())
                            .equipmentName(equipmentDO.getEquipmentName())
                            .userName(equipmentDO.getUserName())
                            .departmentName(equipmentDO.getDepartmentName())
                            .logType(2)
                            .content("离线（http）")
                            .departmentId(equipmentDO.getDepartmentId())
                            .companyId(equipmentDO.getCompanyId())
                            .operateTime(new Date())
                            .build();
                    logUserOnlineDOList.add(logUserOnlineDO);
                }
            });

            if (CollectionUtils.isNotEmpty(offlineEquipmentIdList)) {
                new LambdaUpdateChainWrapper<>(equipmentDao)
                        .set(DeviceEquipmentDO::getEquipmentState, EquipmentStateEnum.OFFLINE.getState())
                        .set(DeviceEquipmentDO::getOfflineTime, new Date())
                        .eq(DeviceEquipmentDO::getEquipmentState, EquipmentStateEnum.HTTP_ONLINE.getState())
                        .in(DeviceEquipmentDO::getId, offlineEquipmentIdList)
                        .update();
                log.info("http心跳检测离线：{}", JSONUtil.toJsonStr(offlineEquipmentIdList));
            }
            if (CollectionUtils.isNotEmpty(logUserOnlineDOList)) {
                logUserOnlineDao.insertBatch(logUserOnlineDOList);
            }
        }
        log.info("http心跳检测完成 耗时：{}秒", timer.intervalSecond());
    }
}
