/**
 * Copyright 2019 DH
 * All right reserved.
 * 项目名称: 山洪灾害运维系统
 * 创建日期:2023/8/4
 */
package org.springblade.jobtask;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
import org.springblade.core.tool.utils.Func;
import org.springblade.enums.WarningActiveEnum;
import org.springblade.modules.baseinfo.rtu.entity.RtuInfoEntity;
import org.springblade.modules.baseinfo.rtu.service.IRtuBaseInfoService;
import org.springblade.modules.baseinfo.warn.entity.BaseWarnSettingEntity;
import org.springblade.modules.baseinfo.warn.service.IBaseWarnSettingService;
import org.springblade.modules.business.warning.service.IRtuWarningService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/***
 * Date:2023/8/4
 * Title: 预警统计功能
 * Description： 雨量5分钟延时预警、离线预警、漏报预警、延时预警、时钟预警、异常值预警
 * @author dylan
 * @version 1.0
 * Remark：认为有必要的其他信息
 */
@Slf4j
@Component
@EnableScheduling
public class WarnCheckProcessor {
	private static ThreadFactory warnCheckThreadFactory = new ThreadFactoryBuilder().setNameFormat("warn-check-thread-pool-%d").build();
	private static ExecutorService warnCheckThreadPool = new ThreadPoolExecutor(1, 1,
		0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(1024), warnCheckThreadFactory, new ThreadPoolExecutor.AbortPolicy());

	@Value("${spring.task-config.warning-check-task}")
	private boolean warnCheckTaskRun;

	@Value("${spring.warn-config.delay-duration}")
	private Integer hourDelayduration;

	@Value("${spring.warn-config.delay-min-duration}")
	private Integer minDelayduration;

	@Value("${spring.warn-config.missout}")
	private Integer missOutNum;

	@Resource
	private IRtuBaseInfoService rtuBaseInfoService;

	@Resource
	private IRtuWarningService rtuWarningService;

	@Resource
	private IBaseWarnSettingService warnSettingService;

	/**
	 * 每5分钟执行一次
	 */
//	@Scheduled(cron = "10 0/5 * * * * ")
	public void warnMinTask() {
		try {
			if (warnCheckTaskRun) {
				log.info("雨量5分钟延时预警统计任务创建 {}", Func.formatDateTime(new Date()));
				LocalDateTime now = LocalDateTime.now();
				WarningCheckMinTask warningTask = new WarningCheckMinTask(now.withSecond(0).withNano(0));
				FutureTask<Integer> futureTask = new FutureTask<>(warningTask);
				warnCheckThreadPool.execute(futureTask);
			}
		} catch (Exception e) {
			log.error("{}", e.getMessage());
		}
	}

	/**
	 * 每10分钟执行一次
	 */
	@Scheduled(cron = "20 0/10 * * * * ")
	public void warnHourTask() {
		try {
			if (warnCheckTaskRun) {
				log.info("预警统计任务创建 {}", Func.formatDateTime(new Date()));
				LocalDateTime now = LocalDateTime.now();
				WarningCheckTask warningTask = new WarningCheckTask(now.withSecond(0).withNano(0));
				FutureTask<Integer> futureTask = new FutureTask<>(warningTask);
				warnCheckThreadPool.execute(futureTask);
			}
		} catch (Exception e) {
			log.error("{}", e.getMessage());
		}
	}

	private class WarningCheckMinTask implements Callable<Integer> {

		private LocalDateTime checkTime;

		public WarningCheckMinTask(LocalDateTime checkTime) {
			this.checkTime = checkTime;
		}

		@Override
		public Integer call() throws Exception {
			long startTime = System.currentTimeMillis();
			try {
				log.info("每5分钟预警检测任务开始执行 {}", Func.formatDateTime(checkTime));
				//测站检测参数
				BaseWarnSettingEntity warnSettingEntity = new BaseWarnSettingEntity();
				//预警开关
				warnSettingEntity.setWarnActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnClockActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnOfflineActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnMissOutActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnOutlierValueActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnHourUpDelayActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnMinUpDelayActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				//延时，小时
				warnSettingEntity.setWarnRainDelayHourDuration(hourDelayduration);
				warnSettingEntity.setWarnRiverDelayHourDuration(hourDelayduration);
				warnSettingEntity.setWarnRsvrDelayHourDuration(hourDelayduration);
				warnSettingEntity.setWarnGroundDelayHourDuration(hourDelayduration);
				//延时，分钟
				warnSettingEntity.setWarnRainDelayMinDuration(minDelayduration);
				warnSettingEntity.setWarnRiverDelayMinDuration(minDelayduration);
				warnSettingEntity.setWarnRsvrDelayMinDuration(minDelayduration);
				warnSettingEntity.setWarnGroundDelayMinDuration(minDelayduration);
				//延时，离线
				warnSettingEntity.setWarnRainOfflineDuration(minDelayduration);
				warnSettingEntity.setWarnRiverOfflineDuration(minDelayduration);
				warnSettingEntity.setWarnRsvrOfflineDuration(minDelayduration);
				warnSettingEntity.setWarnGroundOfflineDuration(minDelayduration);
				//漏报，预警数量
				warnSettingEntity.setWarnMissNum(missOutNum);
				//读取预警配置
				LambdaQueryWrapper<BaseWarnSettingEntity> warnSettingWrapper = Wrappers.<BaseWarnSettingEntity>query().lambda();
				warnSettingWrapper.eq(BaseWarnSettingEntity::getIsDeleted, 0);
				List<BaseWarnSettingEntity> warnSettingEntityList = warnSettingService.list(warnSettingWrapper);
				if (null != warnSettingEntityList && warnSettingEntityList.size() > 0) {
					if (warnSettingEntityList.get(0).getWarnActive() != null) {
						warnSettingEntity.setWarnActive(warnSettingEntityList.get(0).getWarnActive());
					}
					if (warnSettingEntityList.get(0).getWarnClockActive() != null) {
						warnSettingEntity.setWarnClockActive(warnSettingEntityList.get(0).getWarnClockActive());
					}
					if (warnSettingEntityList.get(0).getWarnOfflineActive() != null) {
						warnSettingEntity.setWarnOfflineActive(warnSettingEntityList.get(0).getWarnOfflineActive());
					}
					if (warnSettingEntityList.get(0).getWarnMissOutActive() != null) {
						warnSettingEntity.setWarnMissOutActive(warnSettingEntityList.get(0).getWarnMissOutActive());
					}
					if (warnSettingEntityList.get(0).getWarnOutlierValueActive() != null) {
						warnSettingEntity.setWarnOutlierValueActive(warnSettingEntityList.get(0).getWarnOutlierValueActive());
					}
					if (warnSettingEntityList.get(0).getWarnHourUpDelayActive() != null) {
						warnSettingEntity.setWarnHourUpDelayActive(warnSettingEntityList.get(0).getWarnHourUpDelayActive());
					}
					if (warnSettingEntityList.get(0).getWarnMinUpDelayActive() != null) {
						warnSettingEntity.setWarnMinUpDelayActive(warnSettingEntityList.get(0).getWarnMinUpDelayActive());
					}
					if (warnSettingEntityList.get(0).getWarnRainDelayHourDuration() != null) {
						warnSettingEntity.setWarnRainDelayHourDuration(warnSettingEntityList.get(0).getWarnRainDelayHourDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRiverDelayHourDuration() != null) {
						warnSettingEntity.setWarnRiverDelayHourDuration(warnSettingEntityList.get(0).getWarnRiverDelayHourDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRsvrDelayHourDuration() != null) {
						warnSettingEntity.setWarnRsvrDelayHourDuration(warnSettingEntityList.get(0).getWarnRsvrDelayHourDuration());
					}
					if (warnSettingEntityList.get(0).getWarnGroundDelayHourDuration() != null) {
						warnSettingEntity.setWarnGroundDelayHourDuration(warnSettingEntityList.get(0).getWarnGroundDelayHourDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRainDelayMinDuration() != null) {
						warnSettingEntity.setWarnRainDelayMinDuration(warnSettingEntityList.get(0).getWarnRainDelayMinDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRiverDelayMinDuration() != null) {
						warnSettingEntity.setWarnRiverDelayMinDuration(warnSettingEntityList.get(0).getWarnRiverDelayMinDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRsvrDelayMinDuration() != null) {
						warnSettingEntity.setWarnRsvrDelayMinDuration(warnSettingEntityList.get(0).getWarnRsvrDelayMinDuration());
					}
					if (warnSettingEntityList.get(0).getWarnGroundDelayMinDuration() != null) {
						warnSettingEntity.setWarnGroundDelayMinDuration(warnSettingEntityList.get(0).getWarnGroundDelayMinDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRainOfflineDuration() != null) {
						warnSettingEntity.setWarnRainOfflineDuration(warnSettingEntityList.get(0).getWarnRainOfflineDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRiverOfflineDuration() != null) {
						warnSettingEntity.setWarnRiverOfflineDuration(warnSettingEntityList.get(0).getWarnRiverOfflineDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRsvrOfflineDuration() != null) {
						warnSettingEntity.setWarnRsvrOfflineDuration(warnSettingEntityList.get(0).getWarnRsvrOfflineDuration());
					}
					if (warnSettingEntityList.get(0).getWarnGroundOfflineDuration() != null) {
						warnSettingEntity.setWarnGroundOfflineDuration(warnSettingEntityList.get(0).getWarnGroundOfflineDuration());
					}
					if (warnSettingEntityList.get(0).getWarnMissNum() != null) {
						warnSettingEntity.setWarnMissNum(warnSettingEntityList.get(0).getWarnMissNum());
					}
				}
				//开始检测
				if (warnSettingEntity.getWarnActive() == WarningActiveEnum.ACTIVE_OPEN.getCode()) {
					LambdaQueryWrapper<RtuInfoEntity> dataWrapper = Wrappers.<RtuInfoEntity>query().lambda();
					dataWrapper.eq(RtuInfoEntity::getIsDeleted, 0);
					dataWrapper.orderByAsc(RtuInfoEntity::getRtuCode);
					List<RtuInfoEntity> list = rtuBaseInfoService.list(dataWrapper);
					if (null != list && list.size() > 0) {
						for (RtuInfoEntity entity : list) {
							if (warnSettingEntity.getWarnMinUpDelayActive() == WarningActiveEnum.ACTIVE_OPEN.getCode()) {

								if (entity.getIsRain() == 1) {
									//雨量报5分钟延时检测
									rtuWarningService.checkRtuRainUpDelayStatus(entity, warnSettingEntity, checkTime);
								}
							}
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.error("每5分钟预警检测任务异常 {}", e.getMessage());
			} finally {
				log.info("每5分钟预警检测任务完成 {} 毫秒", System.currentTimeMillis() - startTime);
			}
			return 0;
		}
	}

	private class WarningCheckTask implements Callable<Integer> {

		private LocalDateTime checkTime;

		public WarningCheckTask(LocalDateTime checkTime) {
			this.checkTime = checkTime;
		}

		@Override
		public Integer call() throws Exception {
			long startTime = System.currentTimeMillis();
			try {
				log.info("每小时预警检测任务开始执行 {}", Func.formatDateTime(checkTime));
				//测站检测参数
				BaseWarnSettingEntity warnSettingEntity = new BaseWarnSettingEntity();
				//预警开关
				warnSettingEntity.setWarnActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnClockActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnOfflineActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnMissOutActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnOutlierValueActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnHourUpDelayActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				warnSettingEntity.setWarnMinUpDelayActive(WarningActiveEnum.ACTIVE_OFF.getCode());
				//延时，小时
				warnSettingEntity.setWarnRainDelayHourDuration(hourDelayduration);
				warnSettingEntity.setWarnRiverDelayHourDuration(hourDelayduration);
				warnSettingEntity.setWarnRsvrDelayHourDuration(hourDelayduration);
				warnSettingEntity.setWarnGroundDelayHourDuration(hourDelayduration);
				//延时，分钟
				warnSettingEntity.setWarnRainDelayMinDuration(minDelayduration);
				warnSettingEntity.setWarnRiverDelayMinDuration(minDelayduration);
				warnSettingEntity.setWarnRsvrDelayMinDuration(minDelayduration);
				warnSettingEntity.setWarnGroundDelayMinDuration(minDelayduration);
				//延时，离线
				warnSettingEntity.setWarnRainOfflineDuration(minDelayduration);
				warnSettingEntity.setWarnRiverOfflineDuration(minDelayduration);
				warnSettingEntity.setWarnRsvrOfflineDuration(minDelayduration);
				warnSettingEntity.setWarnGroundOfflineDuration(minDelayduration);
				//漏报，预警数量
				warnSettingEntity.setWarnMissNum(missOutNum);
				//读取预警配置
				LambdaQueryWrapper<BaseWarnSettingEntity> warnSettingWrapper = Wrappers.<BaseWarnSettingEntity>query().lambda();
				warnSettingWrapper.eq(BaseWarnSettingEntity::getIsDeleted, 0);
				List<BaseWarnSettingEntity> warnSettingEntityList = warnSettingService.list(warnSettingWrapper);
				if (null != warnSettingEntityList && warnSettingEntityList.size() > 0) {
					if (warnSettingEntityList.get(0).getWarnActive() != null) {
						warnSettingEntity.setWarnActive(warnSettingEntityList.get(0).getWarnActive());
					}
					if (warnSettingEntityList.get(0).getWarnClockActive() != null) {
						warnSettingEntity.setWarnClockActive(warnSettingEntityList.get(0).getWarnClockActive());
					}
					if (warnSettingEntityList.get(0).getWarnOfflineActive() != null) {
						warnSettingEntity.setWarnOfflineActive(warnSettingEntityList.get(0).getWarnOfflineActive());
					}
					if (warnSettingEntityList.get(0).getWarnMissOutActive() != null) {
						warnSettingEntity.setWarnMissOutActive(warnSettingEntityList.get(0).getWarnMissOutActive());
					}
					if (warnSettingEntityList.get(0).getWarnOutlierValueActive() != null) {
						warnSettingEntity.setWarnOutlierValueActive(warnSettingEntityList.get(0).getWarnOutlierValueActive());
					}
					if (warnSettingEntityList.get(0).getWarnHourUpDelayActive() != null) {
						warnSettingEntity.setWarnHourUpDelayActive(warnSettingEntityList.get(0).getWarnHourUpDelayActive());
					}
					if (warnSettingEntityList.get(0).getWarnMinUpDelayActive() != null) {
						warnSettingEntity.setWarnMinUpDelayActive(warnSettingEntityList.get(0).getWarnMinUpDelayActive());
					}
					if (warnSettingEntityList.get(0).getWarnRainDelayHourDuration() != null) {
						warnSettingEntity.setWarnRainDelayHourDuration(warnSettingEntityList.get(0).getWarnRainDelayHourDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRiverDelayHourDuration() != null) {
						warnSettingEntity.setWarnRiverDelayHourDuration(warnSettingEntityList.get(0).getWarnRiverDelayHourDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRsvrDelayHourDuration() != null) {
						warnSettingEntity.setWarnRsvrDelayHourDuration(warnSettingEntityList.get(0).getWarnRsvrDelayHourDuration());
					}
					if (warnSettingEntityList.get(0).getWarnGroundDelayHourDuration() != null) {
						warnSettingEntity.setWarnGroundDelayHourDuration(warnSettingEntityList.get(0).getWarnGroundDelayHourDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRainDelayMinDuration() != null) {
						warnSettingEntity.setWarnRainDelayMinDuration(warnSettingEntityList.get(0).getWarnRainDelayMinDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRiverDelayMinDuration() != null) {
						warnSettingEntity.setWarnRiverDelayMinDuration(warnSettingEntityList.get(0).getWarnRiverDelayMinDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRsvrDelayMinDuration() != null) {
						warnSettingEntity.setWarnRsvrDelayMinDuration(warnSettingEntityList.get(0).getWarnRsvrDelayMinDuration());
					}
					if (warnSettingEntityList.get(0).getWarnGroundDelayMinDuration() != null) {
						warnSettingEntity.setWarnGroundDelayMinDuration(warnSettingEntityList.get(0).getWarnGroundDelayMinDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRainOfflineDuration() != null) {
						warnSettingEntity.setWarnRainOfflineDuration(warnSettingEntityList.get(0).getWarnRainOfflineDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRiverOfflineDuration() != null) {
						warnSettingEntity.setWarnRiverOfflineDuration(warnSettingEntityList.get(0).getWarnRiverOfflineDuration());
					}
					if (warnSettingEntityList.get(0).getWarnRsvrOfflineDuration() != null) {
						warnSettingEntity.setWarnRsvrOfflineDuration(warnSettingEntityList.get(0).getWarnRsvrOfflineDuration());
					}
					if (warnSettingEntityList.get(0).getWarnGroundOfflineDuration() != null) {
						warnSettingEntity.setWarnGroundOfflineDuration(warnSettingEntityList.get(0).getWarnGroundOfflineDuration());
					}
					if (warnSettingEntityList.get(0).getWarnMissNum() != null) {
						warnSettingEntity.setWarnMissNum(warnSettingEntityList.get(0).getWarnMissNum());
					}
				}
				//开始检测
				if (warnSettingEntity.getWarnActive() == WarningActiveEnum.ACTIVE_OPEN.getCode()) {
					LambdaQueryWrapper<RtuInfoEntity> dataWrapper = Wrappers.<RtuInfoEntity>query().lambda();
					dataWrapper.eq(RtuInfoEntity::getIsDeleted, 0);
					dataWrapper.orderByAsc(RtuInfoEntity::getRtuCode);
					List<RtuInfoEntity> list = rtuBaseInfoService.list(dataWrapper);
					if (null != list && list.size() > 0) {
						for (RtuInfoEntity entity : list) {
							boolean isOffline = false;
							if (warnSettingEntity.getWarnOfflineActive() == WarningActiveEnum.ACTIVE_OPEN.getCode()) {
								//检测离线状态
								isOffline = rtuWarningService.checkRtuOfflineStatus(entity, warnSettingEntity, checkTime);
							}
//							if (warnSettingEntity.getWarnClockActive() == WarningActiveEnum.ACTIVE_OPEN.getCode()) {
//								//检测测站时钟状态
//								if (!isOffline) {
//									rtuWarningService.checkRtuClockStatus(entity, warnSettingEntity, checkTime);
//								}
//							}
//							if (warnSettingEntity.getWarnMissOutActive() == WarningActiveEnum.ACTIVE_OPEN.getCode()) {
//								//离线时，不检测漏报异常
//								if (!isOffline) {
//									if (entity.getIsRain() == 1) {
//										//雨量站小时漏报检测
//										rtuWarningService.checkRtuRainMissOutStatus(entity, warnSettingEntity, checkTime);
//									}
//									if (entity.getIsRiver() == 1) {
//										//河道站小时漏报检测
//										rtuWarningService.checkRtuRiverMissOutStatus(entity, warnSettingEntity, checkTime);
//									}
//									if (entity.getIsRes() == 1) {
//										//水库站小时漏报检测
//										rtuWarningService.checkRtuRsvrMissOutStatus(entity, warnSettingEntity, checkTime);
//									}
//								}
//							}
							if (warnSettingEntity.getWarnHourUpDelayActive() == WarningActiveEnum.ACTIVE_OPEN.getCode()) {
								if (!isOffline) {
//									if (entity.getIsRain() == 1) {
//										//雨量小时报延时检测
//										rtuWarningService.checkRtuRainUpHourDelayStatus(entity, warnSettingEntity, checkTime);
//									}
									//if (entity.getIsRiver() == 1) {
										//河道小时报延时检测
										rtuWarningService.checkRtuRiverUpHourDelayStatus(entity, warnSettingEntity, checkTime);
									//}
//									if (entity.getIsRes() == 1) {
//										//水库小时报延时检测
//										rtuWarningService.checkRtuRsvrUpHourDelayStatus(entity, warnSettingEntity, checkTime);
//									}
								}
							}
//							if (warnSettingEntity.getWarnOutlierValueActive() == WarningActiveEnum.ACTIVE_OPEN.getCode()) {
//								if (!isOffline) {
//									if (entity.getIsRain() == 1) {
//										//疑似异常值
//										rtuWarningService.checkRtuOutlierValueStatus(entity, warnSettingEntity, checkTime);
//									}
//								}
//							}
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
				log.error("预警检测任务异常 {}", e.getMessage());
			} finally {
				log.info("预警检测任务完成 {} 毫秒", System.currentTimeMillis() - startTime);
			}
			return 0;
		}
	}
}
