package org.ts.ddcs.task;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.ts.ddcs.common.util.BytesUtil;
import org.ts.ddcs.constant.BusinessConstant;
import org.ts.ddcs.dataStream.DataStreamManageHolder;
import org.ts.ddcs.main.MainProcessorHolder;

import java.util.Date;
import java.util.concurrent.Callable;

/**
 * 下行报文到RTU
 *
 * @author dylan
 */
@Slf4j
public class DownloadDatagramTask implements Callable<Integer> {

    private String rtuCode;

    public DownloadDatagramTask(String rtuCode) {
        this.rtuCode = rtuCode;
    }

    @Override
    public Integer call() throws Exception {
        try {
            RedisTemplate redisTemplate = MainProcessorHolder.newInstance().dataProcess.redisTemplate;
            HashOperations<String, String, String> opsHash = redisTemplate.opsForHash();
            ListOperations<String, String> opsList = redisTemplate.opsForList();
            if (opsHash.hasKey(rtuCode, "last_connect_id")) {
                String connectId = opsHash.get(rtuCode, "last_connect_id");
                /**升级或下发文件**/
                if (opsHash.hasKey(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_FILE)) {
                    String commandJson = opsHash.get(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_FILE);
                    JSONObject command = JSONObject.parseObject(commandJson);
                    Date now = new Date();
                    long tryCount = command.getLong("tryCount");
                    String relaydatagram = command.getString(BusinessConstant.BASE_KEY_DATAGRAM);
                    if (null != relaydatagram) {
                        String outDatagram = "";
                        if (relaydatagram.startsWith("7E7E")) {
                            String p1 = relaydatagram.substring(0, 32);
                            String p2 = BytesUtil.byte2HexStr(BytesUtil.getFBTm());
                            String p3 = relaydatagram.substring(44, relaydatagram.length() - 4);
                            String body = p1 + p2 + p3;
                            byte[] bodyBuff = BytesUtil.hexStr2Bytes(body);
                            byte[] crc16 = BytesUtil.crcFun2014(bodyBuff);
                            bodyBuff = BytesUtil.arrayApend(bodyBuff, crc16);
                            outDatagram = BytesUtil.byte2HexStr(bodyBuff);
                        } else {
                            outDatagram = relaydatagram;
                        }
                        if (DataStreamManageHolder.newInstance().dataStreamManager.responseEvent(connectId, BytesUtil.hexStr2Bytes(outDatagram))) {
                            command.put("tryCount", tryCount + 1);
                            command.put("lastSendTime", now.getTime());
                            opsHash.put(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_FILE, command.toJSONString());
                            log.info("下发成功 rtuCode {}", rtuCode);
                        } else {
                            log.info("下发失败 rtuCode {}", rtuCode);
                        }
                    }
                    return 0;
                }
                Long size = opsList.size(rtuCode + ":" + BusinessConstant.REDIS_KEY_COMMAND_FILE);
                if (null != size && size > 0) {
                    //  if (redisTemplate.hasKey(rtuCode + ":" + BusinessConstant.REDIS_KEY_COMMAND_FILE)) {
                    // if (opsList.size(rtuCode + ":" + BusinessConstant.REDIS_KEY_COMMAND_FILE) > 0) {
                    if (opsHash.hasKey(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_FILE)) {
                        opsHash.delete(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_FILE);
                    }
                    String commandJson = opsList.leftPop(rtuCode + ":" + BusinessConstant.REDIS_KEY_COMMAND_FILE);
                    JSONObject command = JSONObject.parseObject(commandJson);
                    Date now = new Date();
                    String relaydatagram = command.getString(BusinessConstant.BASE_KEY_DATAGRAM);
                    if (null != relaydatagram) {
                        String outDatagram = "";
                        if (relaydatagram.startsWith("7E7E")) {
                            String p1 = relaydatagram.substring(0, 32);
                            String p2 = BytesUtil.byte2HexStr(BytesUtil.getFBTm());
                            String p3 = relaydatagram.substring(44, relaydatagram.length() - 4);
                            String body = p1 + p2 + p3;
                            byte[] bodyBuff = BytesUtil.hexStr2Bytes(body);
                            byte[] crc16 = BytesUtil.crcFun2014(bodyBuff);
                            bodyBuff = BytesUtil.arrayApend(bodyBuff, crc16);//CRC16
                            outDatagram = BytesUtil.byte2HexStr(bodyBuff);
                        } else {
                            outDatagram = relaydatagram;
                        }
                        if (DataStreamManageHolder.newInstance().dataStreamManager.responseEvent(connectId, BytesUtil.hexStr2Bytes(outDatagram))) {
                            long tryCount = 1;
                            command.put("try", true);
                            command.put("tryCount", tryCount);
                            command.put("lastSendTime", now.getTime());
                            if (command.containsKey("waittingBack")) {
                                boolean waittingBack = command.getBoolean("waittingBack");
                                if (waittingBack) {
                                    opsHash.put(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_FILE, command.toJSONString());
                                }
                            } else {
                                opsHash.put(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_FILE, command.toJSONString());
                            }
                            log.info("下发成功 rtuCode {}", rtuCode);
                        } else {
                            log.info("下发失败 rtuCode {}", rtuCode);
                        }
                    }
                    return 0;
                }
                //   }
                if (opsHash.hasKey(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_SETTING)) {
                    String commandJson = opsHash.get(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_SETTING);
                    if (null != commandJson && !"".equals(commandJson)) {
                        JSONObject command = JSONObject.parseObject(commandJson);
                        long tryCount = command.getLong("tryCount");
                        if (tryCount < 5) {
                            Date now = new Date();
                            String relaydatagram = command.getString(BusinessConstant.BASE_KEY_DATAGRAM);
                            if (null != relaydatagram) {
                                if (DataStreamManageHolder.newInstance().dataStreamManager.responseEvent(connectId, BytesUtil.hexStr2Bytes(relaydatagram))) {
                                    command.put("tryCount", tryCount + 1);
                                    command.put("lastSendTime", now.getTime());
                                    opsHash.put(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_SETTING, command.toJSONString());
                                    log.info("下发成功 rtuCode {}", rtuCode);
                                } else {
                                    log.info("下发失败 rtuCode {}", rtuCode);
                                }
                            }
                        } else {
                            opsHash.delete(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_SETTING);
                        }
                        return 0;
                    }
                }
                //  if (redisTemplate.hasKey(rtuCode + ":" + BusinessConstant.REDIS_KEY_COMMAND_SETTING)) {
                size = opsList.size(rtuCode + ":" + BusinessConstant.REDIS_KEY_COMMAND_SETTING);
                if (null != size && size > 0) {
                    //  if (opsList.size(rtuCode + ":" + BusinessConstant.REDIS_KEY_COMMAND_SETTING) > 0) {
                    String commandJson = opsList.leftPop(rtuCode + ":" + BusinessConstant.REDIS_KEY_COMMAND_SETTING);
                    JSONObject command = JSONObject.parseObject(commandJson);
                    Date now = new Date();
                    String relaydatagram = command.getString(BusinessConstant.BASE_KEY_DATAGRAM);
                    if (null != relaydatagram) {
                        if (DataStreamManageHolder.newInstance().dataStreamManager.responseEvent(connectId, BytesUtil.hexStr2Bytes(relaydatagram))) {
                            long tryCount = 1;
                            command.put("tryCount", tryCount);
                            command.put("lastSendTime", now.getTime());
                            command.put("try", true);
                            if (command.containsKey("waittingBack")) {
                                boolean waittingBack = command.getBoolean("waittingBack");
                                if (waittingBack) {
                                    opsHash.put(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_SETTING, command.toJSONString());
                                }
                            } else {
                                opsHash.put(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_SETTING, command.toJSONString());
                            }
                            log.info("下发成功 rtuCode {}", rtuCode);
                        } else {
                            log.info("下发失败 rtuCode {}", rtuCode);
                        }
                    }
                    return 0;
                }
                //   }
                if (opsHash.hasKey(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_QUERY)) {
                    String commandJson = opsHash.get(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_QUERY);
                    if (null != commandJson && !"".equals(commandJson)) {
                        JSONObject command = JSONObject.parseObject(commandJson);
                        long tryCount = command.getLong("tryCount");
                        if (tryCount < 5) {
                            Date now = new Date();
                            long lastSendTime = command.getLong("lastSendTime");
                            long currTime = now.getTime();
                            String relaydatagram = command.getString(BusinessConstant.BASE_KEY_DATAGRAM);
                            if (null != relaydatagram) {
                                if (DataStreamManageHolder.newInstance().dataStreamManager.responseEvent(connectId, BytesUtil.hexStr2Bytes(relaydatagram))) {
                                    command.put("tryCount", tryCount + 1);
                                    command.put("lastSendTime", now.getTime());
                                    opsHash.put(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_QUERY, command.toJSONString());
                                    log.info("下发成功 rtuCode {}", rtuCode);
                                } else {
                                    log.info("下发失败 rtuCode {}", rtuCode);
                                }
                            }
                        } else {
                            opsHash.delete(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_QUERY);
                        }
                        return 0;
                    }
                }
                //   Boolean isCommandList = redisTemplate.hasKey(rtuCode + ":" + BusinessConstant.REDIS_KEY_COMMAND_QUERY);
                // if (null != isCommandList && isCommandList) {
                size = opsList.size(rtuCode + ":" + BusinessConstant.REDIS_KEY_COMMAND_QUERY);
                if (null != size && size > 0) {
                    String commandJson = opsList.leftPop(rtuCode + ":" + BusinessConstant.REDIS_KEY_COMMAND_QUERY);
                    JSONObject command = JSONObject.parseObject(commandJson);
                    Date now = new Date();
                    String relaydatagram = command.getString(BusinessConstant.BASE_KEY_DATAGRAM);
                    if (null != relaydatagram) {
                        if (DataStreamManageHolder.newInstance().dataStreamManager.responseEvent(connectId, BytesUtil.hexStr2Bytes(relaydatagram))) {
                            long tryCount = 1;
                            command.put("tryCount", tryCount);
                            command.put("lastSendTime", now.getTime());
                            command.put("try", true);
                            if (command.containsKey("waittingBack")) {
                                boolean waittingBack = command.getBoolean("waittingBack");
                                if (waittingBack) {
                                    opsHash.put(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_QUERY, command.toJSONString());
                                }
                            } else {
                                opsHash.put(rtuCode, BusinessConstant.REDIS_KEY_COMMAND_QUERY, command.toJSONString());
                            }
                            log.info("下发成功 rtuCode {}", rtuCode);
                        } else {
                            log.info("下发失败 rtuCode {}", rtuCode);
                        }
                    }
                }
                // }
            }
        } catch (Exception e) {
            log.error("toRtu", e);
        }
        return 0;
    }
}
