package org.ts.ddcs.worker;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.ts.ddcs.log.LogHelper;
import org.ts.ddcs.tool.GBConstants;
import org.ts.ddcs.tool.RedisHelper;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Callable;

public class LogMapWorker implements Callable<Integer> {

    private JSONObject log;

    LogMapWorker(JSONObject log) {
        this.log = log;
    }

    @Override
    public Integer call() {
        String LogId = LogHelper.createLogId("LogMapWorker");
        try {
            RedisTemplate redisTemplate = DataProcessHolder.newInstance().dataProcess.redisTemplate;
            if (null == redisTemplate) {
                return 0;
            }
            LogHelper.info(LogId + " " + log.getString("agreement") + " " + log.getString("logTime") + " " + log.getString("rtu") + " " + log.getString("datagram"));
            ListOperations<String, String> opsList = redisTemplate.opsForList();
            HashOperations<String, String, String> opsHash = redisTemplate.opsForHash();
            String logTime = log.getString("logTime");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date dt = sdf.parse(logTime);
            String agreement = log.getString("agreement");
            String rtuCode = log.getString("rtu");
            String datagram = log.getString("datagram");

            DataProcessHolder.newInstance().dataProcess.databaseService.saveDatagram(rtuCode, dt, datagram);

            //生成测站规约
            if (agreement.equals(GBConstants.AGREEMENT_KIND_SW)) {

            } else {
                if (opsHash.hasKey(rtuCode, GBConstants.REDIS_KEY_PROJECT_ID)) {
                    String project_key = GBConstants.REDIS_KEY_PROJECT_PREFIX + opsHash.get(rtuCode, GBConstants.REDIS_KEY_PROJECT_ID);
                    if (opsHash.hasKey(project_key, GBConstants.REDIS_KEY_AGREEMENT)) {
                        agreement = opsHash.get(project_key, GBConstants.REDIS_KEY_AGREEMENT);
                    }
                }
            }
            //更新最近一天的小时报文列表
            String list_hour_key = rtuCode + ":List:Hour";
            if (RedisHelper.hasKey(list_hour_key, redisTemplate)) {
                String last = opsList.rightPop(list_hour_key);
                if (last.substring(0, "yyyy-MM-dd HH".length()).equals(logTime.substring(0, "yyyy-MM-dd HH".length()))) {
                    opsList.rightPush(list_hour_key, logTime);
                } else {
                    opsList.rightPush(list_hour_key, last);
                    opsList.rightPush(list_hour_key, logTime);
                }
            } else {
                opsList.rightPush(list_hour_key, logTime);
            }
            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMddHH");
            Long size = opsList.size(list_hour_key);
            if (size > 24) {
                String left = opsList.leftPop(list_hour_key);
                Date deleteDt = sdf.parse(left);
                String deletehour = sdf2.format(deleteDt.getTime());
                String delete_key = rtuCode + ":List:Minute:" + deletehour;
                redisTemplate.delete(delete_key);
            }
            //更新每小时的报文列表
            String hourStr = sdf2.format(dt.getTime());
            String list_minute_key = rtuCode + ":List:Minute:" + hourStr;
            JSONObject info = new JSONObject();
            info.put("datagram", datagram);
            String dataOfMinute = logTime + "=" + info.toJSONString();
            opsList.rightPush(list_minute_key, dataOfMinute);

            //更新最近50条报文
            SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMddHHmmss");
            opsList.rightPush(rtuCode + ":List", logTime);
            String datagramTime = sdf3.format(dt.getTime());
            opsHash.put(rtuCode + ":datagram", datagramTime, datagram);
            size = opsList.size(rtuCode + ":List");
            if (size > 50) {
                String lefttime = opsList.leftPop(rtuCode + ":List");
                Date tmpdt = sdf.parse(lefttime);
                String tmpdatagramTime = sdf3.format(tmpdt.getTime());
                opsHash.delete(rtuCode + ":datagram", tmpdatagramTime);
            }

            opsHash.put(rtuCode, "datagram", datagram);
            opsHash.put(rtuCode, "agreement", agreement);

            if (opsHash.hasKey(rtuCode, "lastTime")) {
                String lastTime = opsHash.get(rtuCode, "lastTime");
                Date lastdt = sdf.parse(lastTime);
                long diff = dt.getTime() - lastdt.getTime();
                opsHash.put(rtuCode, "spaceTime", Long.toString(diff));
                opsHash.put(rtuCode, "lastTime", logTime);
            } else {
                opsHash.put(rtuCode, "spaceTime", "0");
                opsHash.put(rtuCode, "lastTime", logTime);
            }

            DataProcessHolder.newInstance().dataProcess.databaseService.updateLastTime(rtuCode,dt);

            //更新在线状态
            opsHash.put("rtu_online", rtuCode, logTime);



          //  List<String> msgList = new ArrayList();
            //并发连接
//            Calendar calendar = Calendar.getInstance();
//            calendar.setTime(dt);
//            int year = calendar.get(Calendar.YEAR);
//            int month = calendar.get(Calendar.MONTH);
//            int day = calendar.get(Calendar.DAY_OF_MONTH);
//            int hour = calendar.get(Calendar.HOUR_OF_DAY);
//            int mintue = calendar.get(Calendar.MINUTE);
//            int onlineNum = 0;
//            List<String> rtu_online = opsHash.values("rtu_online");
//            for (String tm : rtu_online) {
//                Date t = sdf.parse(tm);
//                calendar.setTime(t);
//                int year2 = calendar.get(Calendar.YEAR);
//                int month2 = calendar.get(Calendar.MONTH);
//                int day2 = calendar.get(Calendar.DAY_OF_MONTH);
//                int hour2 = calendar.get(Calendar.HOUR_OF_DAY);
//                int mintue2 = calendar.get(Calendar.MINUTE);
//                if (year == year2 && month == month2 && day == day2 && hour == hour2 && mintue == mintue2) {
//                    onlineNum += 1;
//                }
//            }
//            JSONObject msg = new JSONObject();
//            msg.put("msg_code", "online_rtu_num");
//            msg.put("name", "在线数量");
//            msg.put("value", String.format("%d", onlineNum));
//            msgList.add(msg.toJSONString());
//

            //1小时累计
//            calendar.setTime(dt);
//            calendar.add(Calendar.HOUR_OF_DAY, -1);
//            Date startTime = calendar.getTime();
//            calendar.setTime(dt);
//            Date endTime = calendar.getTime();
//
//            long datagramNum = DataProcessHolder.newInstance().dataProcess.databaseService.datagramCount(startTime, endTime);
//            msg = new JSONObject();
//            msg.put("msg_code", "datagram_up_num_in_hour");
//            msg.put("name", "1小时报文上报数量");
//            msg.put("value", String.format("%d", datagramNum));
//            msgList.add(msg.toJSONString());
//
//            //峰值
//            boolean nextPeakValue = false;
//            calendar.setTime(dt);
//            year = calendar.get(Calendar.YEAR);
//            month = calendar.get(Calendar.MONTH);
//            day = calendar.get(Calendar.DAY_OF_MONTH);
//            hour = calendar.get(Calendar.HOUR_OF_DAY);
//            mintue = calendar.get(Calendar.MINUTE);
//            mintue = mintue < 5 ? 0 : mintue - (mintue % 5);
//            if (redisTemplate.hasKey("datagram_real_peak_value")) {
//                String peakvalue = opsList.rightPop("datagram_real_peak_value");
//                String[] peakvalueList = peakvalue.split(":");
//                if (peakvalueList[1].equals(String.format("%04d%02d%02d%02d%02d", year, month, day, hour, mintue))) {
//                    opsList.rightPush("datagram_real_peak_value", String.format("%d", Integer.parseInt(peakvalueList[0]) + 1) + ":" + String.format("%04d%02d%02d%02d%02d", year, month, day, hour, mintue));
//                } else {
//                    opsList.rightPush("datagram_real_peak_value", peakvalue);
//                    opsList.rightPush("datagram_real_peak_value", "1:" + String.format("%04d%02d%02d%02d%02d", year, month, day, hour, mintue));
//                    nextPeakValue = true;
//                }
//            } else {
//                opsList.rightPush("datagram_real_peak_value", "1:" + String.format("%04d%02d%02d%02d%02d", year, month, day, hour, mintue));
//            }
//            if (opsList.size("datagram_real_peak_value") > 12) {
//                opsList.leftPop("datagram_real_peak_value");
//            }
//            if (nextPeakValue) {
//                List<String> peakValue = opsList.range("datagram_real_peak_value", 0, 11);
//                JSONArray peakValueMsg = new JSONArray();
//                for (String peak : peakValue) {
//                    String[] peakvalueList = peak.split(":");
//                    JSONObject d = new JSONObject();
//                    d.put("name", Integer.parseInt(peakvalueList[1].substring(10, 12)) + "分");
//                    d.put("value", Integer.parseInt(peakvalueList[0]));
//                    peakValueMsg.add(d);
//                }
//
//                msg = new JSONObject();
//                msg.put("msg_code", "datagram_up_peak_value_in_hour");
//                msg.put("list", peakValueMsg);
//                msgList.add(msg.toJSONString());
//            }
//            int goingSecond = (int) ((dt.getTime() - DataProcessHolder.newInstance().dataProcess.msgNotifyTime) / 1000);
//            if (goingSecond >= 2) {
//                DataProcessHolder.newInstance().dataProcess.mqttServer.send(msgList);
//                DataProcessHolder.newInstance().dataProcess.msgNotifyTime = dt.getTime();
//            }
        } catch (Exception e) {
            LogHelper.error(LogId + " " + e);
        }
        return 0;
    }
}
