package com.imdroid.beidou_ehm.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.imdroid.secapi.dto.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class WarningService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    WarningCfgMapper warningCfgMapper;
    @Autowired
    WarningMsgMapper warningMsgMapper;
    // warning type <-> level & value
    Map<Integer, int[]> cfgMap = new ConcurrentHashMap<>();
    int warningLevel2Code = 0;

    @PostConstruct
    public void refreshCfg(){
        QueryWrapper<WarningCfg> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("devicetype", WarningCfg.TYPE_GNSS);
        List<WarningCfg> cfgList = warningCfgMapper.selectList(null);
        cfgMap.clear();
        for(WarningCfg cfg: cfgList){
            cfgMap.put(cfg.getType(),new int[]{cfg.getLevel(),cfg.getValue()});
            if(cfg.getLevel() == WarningCfg.LEVEL_2){
                warningLevel2Code |= cfg.getType();
            }
        }
    }

    public boolean check(GnssStatus curStatus, int warningType, String warningName,
                  boolean isLessCmp, Integer value1, Integer value2, String auxInfo){
        boolean isUpdated=false;
        int newWarningCode = 0;
        int[] warningValues = cfgMap.get(warningType);
        if(warningValues!=null){
            if(isLessCmp) {
                if (value1 != null && value1 <= warningValues[1]) {
                    newWarningCode = warningType;
                }
                if (value2 != null && value2 <= warningValues[1]) {
                    newWarningCode = warningType;
                }
            }
            else{
                if (value1 != null && value1 >= warningValues[1]) {
                    newWarningCode = warningType;
                }
                if (value2 != null && value2 >= warningValues[1]) {
                    newWarningCode = warningType;
                }
            }
        }

        int oldWarningCode = curStatus.getWarningcode() & warningType;
        if(newWarningCode != oldWarningCode){
            if(newWarningCode == 0){
                clearWarning(curStatus, warningType);
            }
            else {
                WarningMsg warningMsg = new WarningMsg();
                warningMsg.setDeviceid(curStatus.getDeviceid());
                warningMsg.setTenantid(curStatus.getTenantid());
                warningMsg.setCreatetime(LocalDateTime.now());
                warningMsg.setDevicetype(WarningCfg.TYPE_GNSS);
                warningMsg.setCode(warningType);
                warningMsg.setLevel((short) warningValues[0]);
                if(auxInfo ==null) {
                    auxInfo = warningName + ":" + value1;
                    if (value2 != null) auxInfo = auxInfo + "," + value2;
                }
                else auxInfo = warningName + ":" + auxInfo;
                warningMsg.setInfo(auxInfo);
                warningMsgMapper.insert(warningMsg);
                //告警级别
                curStatus.setWarningcode(curStatus.getWarningcode() | warningType);

                // 新告警出现后，生成对应设备的 warning 日志文件
                //generate_warning_logs(curStatus.getDeviceid(),warningType,auxInfo);
            }
            isUpdated = true;
        }
        return isUpdated;
    }

    public short getWarningLevel(int warningCode){
        if(warningCode == 0) return WarningCfg.LEVEL_0;
        else if((warningCode & warningLevel2Code) !=0 ) return WarningCfg.LEVEL_2;
        else return WarningCfg.LEVEL_1;
    }

    public void clearWarning(GnssStatus status, int warningCode){
        status.setWarningcode(status.getWarningcode()&~warningCode);
        logger.info("{} clearWarning code {},{}",status.getDeviceid(),warningCode,status.getWarningcode());
        QueryWrapper<WarningMsg> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deviceid",status.getDeviceid());
        queryWrapper.eq("code",warningCode);
        queryWrapper.orderByDesc("createtime");
        queryWrapper.last("limit 1");
        WarningMsg warningMsg = warningMsgMapper.selectOne(queryWrapper);
        if(warningMsg!=null){
            warningMsg.setCleartime(LocalDateTime.now());
            warningMsgMapper.updateById(warningMsg);
        }
    }
}
