package com.imdroid.beidou.config;

import com.imdroid.secapi.dto.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;

/***
 * 定时任务：
 * 1、定时清理消息表（缺省保留3个月）
 * 2、定时清理原始数据表（缺省保留1个月）
 * 3、定时清理操作日志（缺省保留1年）
 * 3、定时检查设备是否在线
 */

@Slf4j
@Configuration
@EnableScheduling
public class SchedulingConfig {
    @Autowired
    GnssStatusMapper gnssStatusMapper;
    @Autowired
    GnssMsgMapper gnssMsgMapper;
    @Autowired
    GnssStatusMsgMapper statusMsgMapper;
    @Autowired
    GnssTrxMsgMapper trxMsgMapper;
    @Autowired
    GnssRawDataMapper rawDataMapper;

    @Autowired
    GnssGroupMapper groupMapper;

    @Autowired
    WarningMsgMapper warningMsgMapper;


    //cron表达式格式：
    //{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}

    @Scheduled(cron = "0 10 0 * * *") // 每天凌晨执行一次(0:10:0)
    //@Scheduled(cron = "0 */2 * * * ?") // 每60分钟执行一次
    //@Scheduled(cron = "*/5 * * * * ?") // 每5秒执行一次
    public void dayTask() {
        checkMsgDataset();
        checkRawDataset();
    }

    @Scheduled(cron = "0 18 * * * ?") // 每小时的18分钟执行一次
    public void hourTask() {
        checkDeviceState();
    }

    void checkMsgDataset(){
        long before = System.currentTimeMillis() -
                (long)90 * 24 * 3600 * 1000;
        Timestamp t = new Timestamp(before);
        int count = gnssMsgMapper.deleteTimeBefore(t);
        log.info("clean msg dataset num: "+count);
        count = statusMsgMapper.deleteTimeBefore(t);
        log.info("clean status msg dataset num: "+count);
        count = trxMsgMapper.deleteTimeBefore(t);
        log.info("clean trx msg dataset num: "+count);
    }

    void checkRawDataset(){
        long before = System.currentTimeMillis() -
                (long)30 * 24 * 3600 * 1000;
        Timestamp t = new Timestamp(before);
        int count = rawDataMapper.deleteTimeBefore(t);
        log.info("clean raw dataset num: "+count);
    }


    void checkDeviceState(){
        List<GnssGroup> groupCfgs = groupMapper.selectList(null);
        HashMap<Integer,Integer> group_cycle_map=new HashMap<>();
        for(GnssGroup g:groupCfgs){
            group_cycle_map.put(g.getId(), g.getWork_cycle());
        }

        LocalDateTime now = LocalDateTime.now();
        List<GnssStatusJoin> deviceStatuses = gnssStatusMapper.queryOnline();
        for(GnssStatusJoin status : deviceStatuses){
            //如果上次上线到现在超过两个周期，则认为掉线了
            LocalDateTime expiredTime = status.getUpdatetime().plusMinutes(group_cycle_map.get(status.getGroup_id())*2);
            if(now.isAfter(expiredTime)){
                status.setState(GnssStatus.STATE_OFFLINE);
                if(status.getWarningcode()==null) status.setWarningcode(0);
                status.setWarningcode(status.getWarningcode() | WarningCfg.TYPE_DEVICE_OFF_LINE);
                status.setWarning(WarningCfg.LEVEL_2);
                gnssStatusMapper.setOfflineByDeviceId(status);
                //告警消息
                WarningMsg warningMsg = new WarningMsg();
                warningMsg.setDevicetype(WarningCfg.TYPE_GNSS);
                warningMsg.setTenantid(status.getTenantid());
                warningMsg.setDeviceid(status.getDeviceid());
                warningMsg.setCreatetime(now);
                warningMsg.setLevel(WarningCfg.LEVEL_2);
                warningMsg.setInfo(WarningCfg.TYPE_NAME_DEVICE_OFF_LINE);
                warningMsg.setCode(WarningCfg.TYPE_DEVICE_OFF_LINE);
                warningMsgMapper.insert(warningMsg);
            }
        }
    }
}