package com.gyee.alarm.task.thread;

import com.gyee.alarm.feigns.IAlarmService;
import com.gyee.alarm.model.vo.*;
import com.gyee.alarm.rule.AlarmFunction;
import com.gyee.alarm.rule.expression.AlarmExpression;
import com.gyee.alarm.rule.expression.Analyzer;
import com.gyee.alarm.service.auto.IAlarmTsService;
import com.gyee.alarm.util.realtimesource.IEdosUtil;
import com.gyee.common.model.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

public class AlarmThread implements Runnable {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private Executor executor;


    private Integer readRows;
    private IAlarmService alarmService;

    private List<AlarmCustomTag> alarmVoList;
    private StringBuilder str;

    private Integer interval;

    private CountDownLatch countDownLatch;

    private  IAlarmTsService alarmTsService;
    public AlarmThread(Executor executor, IAlarmService alarmService, List<AlarmCustomTag> alarmVoList, Integer interval,
                       StringBuilder str, Integer readRows, CountDownLatch countDownLatch,IAlarmTsService alarmTsService) {
        this.executor = executor;
        this.alarmService = alarmService;
        this.alarmVoList = alarmVoList;
        this.interval = interval;
        this.str = str;
        this.readRows = readRows;
        this.countDownLatch = countDownLatch;
        this.alarmTsService = alarmTsService;
    }


    @Override
    public synchronized void run() {


        String task = "task@ " + String.valueOf(str);
        logger.info("创建任务并提交到线程池中：" + task);
        Integer result = 1;

        try {

//			while (runStarted)
//			{

            List<AlarmTag> saveAlarmTags =   new CopyOnWriteArrayList<>();
            List<AlarmTag> updateAlarmTags  = new CopyOnWriteArrayList<>();


            StringBuilder sb = new StringBuilder();


            List<AlarmSimpleVo> alarmls = new CopyOnWriteArrayList<>();
            int times = 0;
            for (AlarmCustomTag alarm : alarmVoList) {

                sb.append("'").append(alarm.getId().toLowerCase()).append("',");
                times++;
                if (times == 1000) {
                    String ids =  sb.substring(0, sb.length() - 1);
                    List<AlarmSimpleVo>  templs=new ArrayList<>();
                    templs =  alarmTsService.selectLastRowByTbname(AlarmSuperTalbeType.CT.getCode(), ids);
                    alarmls.addAll(templs);
                    sb.setLength(0);
                    times = 0;
                }
            }
            if (sb.length()>0) {

                String ids =  sb.substring(0, sb.length() - 1);
                List<AlarmSimpleVo>  templs=new ArrayList<>();
                templs =  alarmTsService.selectLastRowByTbname(AlarmSuperTalbeType.CT.getCode(), ids);
                alarmls.addAll(templs);
            }

            Map<String, AlarmSimpleVo> map = new ConcurrentHashMap<>();


            if (!alarmls.isEmpty()) {
                for (AlarmSimpleVo vo : alarmls) {
                    map.put(vo.getTbName().toLowerCase(), vo);
                }
            }


            for (AlarmCustomTag vo : alarmVoList) {

                checkRule(saveAlarmTags, updateAlarmTags, vo,map);

            }

            if (!saveAlarmTags.isEmpty()) {
                alarmService.saveAlarm(saveAlarmTags);
            }

            if (!updateAlarmTags.isEmpty()) {
                alarmService.updateAlarm(updateAlarmTags);
            }


//				try {
//					Thread.sleep((interval * 1000));
//				} catch (InterruptedException e) {
//					throw new RuntimeException(e);
//				}
//			}
            logger.info(str+ "新增报警数量：" + saveAlarmTags.size());
            logger.info(str+ "结束报警数量：" + updateAlarmTags.size());
        } catch (Exception e) {

            e.printStackTrace();
            result = 0;
        } finally {
            countDownLatch.countDown();
            logger.info("完成任务并提交到线程池中：" + task);
        }
    }

    private synchronized void checkRule(List<AlarmTag> saveAlarmTags, List<AlarmTag> updateAlarmTags, AlarmCustomTag ar, Map<String, AlarmSimpleVo> map) {


        try {

            AlarmExpression alarmExpression = Analyzer.getAlarmExpression(ar.getTagId());

            AlarmFunction alarmFunction = null;

            if (ar.getDevicetype().equals(DeviceTypeValue.WT.getCode())) {
                alarmFunction = new AlarmFunction(alarmExpression, DeviceTypeValue.WT, ar.getDeviceid());


            }else if (ar.getDevicetype().equals(DeviceTypeValue.IN.getCode())) {
                alarmFunction = new AlarmFunction(alarmExpression, DeviceTypeValue.IN, ar.getDeviceid());


            } else if (ar.getDevicetype().equals(DeviceTypeValue.BT.getCode())) {
                alarmFunction = new AlarmFunction(alarmExpression, DeviceTypeValue.BT, ar.getStationid());
            }

            try {

                Object obj = alarmFunction.explain();

                if (obj instanceof Boolean) {


                    boolean endStatus = true;

                    if(map.containsKey(ar.getId().toLowerCase()))
                    {
                        AlarmSimpleVo vo=map.get(ar.getId().toLowerCase());

                        if(StringUtils.notEmp(vo.getEndts()))
                        {
                            endStatus=true;
                        }else
                        {
                            endStatus=false;
                        }
                    }else
                    {
                        endStatus = true;
                    }
                    if (true == (boolean) obj) {

                        if(endStatus)
                        {
                            AlarmTag po = new AlarmTag();
                            po.setId(ar.getId());
                            po.setTs(new Date().getTime());
                            po.setEndts(null);
                            po.setVal(1.0);
                            po.setOval(1.0);
                            po.setTimeLong(0.0);

                            saveAlarmTags.add(po);
                        }

                    } else {

                        if(!endStatus)
                        {
                            AlarmTag po = new AlarmTag();
                            po.setId(ar.getId());
                            po.setTs(new Date().getTime());
                            po.setEndts(new Date().getTime());
                            po.setVal(0.0);
                            po.setOval(0.0);
                            po.setTimeLong(0.0);

                            updateAlarmTags.add(po);
                        }

                    }
                } else {
                    // System.out.print(obj.toString());
                }
            } catch (Exception ex) {
                // ex.printStackTrace();
                logger.error("自定义报警规则执行时出错！" + alarmFunction.getThingId() + "--" + ar.getTagId() + "----" + ex.getMessage());
            }

        } catch (Exception ex) {
            logger.error("生成自定义报警规则失败！规则id：" + ar.getId());
        }
    }

}