package com.inspect.patrol.linkage.processor;

import com.alibaba.fastjson.JSONObject;
import com.inspect.base.core.exception.ServiceException;
import com.inspect.base.core.utils.HexUtils;
import com.inspect.base.core.utils.StringUtils;
import com.inspect.base.core.web.domain.AjaxResult;
import com.inspect.base.redis.service.RedisService;
import com.inspect.partrolresult.service.impl.PatrolResultServiceImpl;
import com.inspect.patrol.contants.LinkageDeviceType;
import com.inspect.patrol.domain.LinkagePatrolTask;
import com.inspect.patrol.domain.LinkageTaskInfo;
import com.inspect.patrol.domain.PatrolLinkagePos;
import com.inspect.patrol.domain.PatrolLinkageStrategy;
import com.inspect.patrol.domain.PopupData;
import com.inspect.patrol.domain.PopupInfoData;
import com.inspect.patrol.linkage.NettyUdpClient;
import com.inspect.patrol.linkage.block.CimeProcessor;
import com.inspect.patrol.linkage.block.DeviceInfoBlock;
import com.inspect.patrol.linkage.block.IBlock;
import com.inspect.patrol.linkage.constain.LinkageContain;
import com.inspect.patrol.linkage.frame.DeviceInfoFrame;
import com.inspect.patrol.linkage.frame.LinkageSignByte;
import com.inspect.patrol.linkage.frame.LinkageSignEntity;
import com.inspect.patrol.linkage.notify.LinkageNotify;
import com.inspect.patrol.service.BasedataAreaService;
import com.inspect.patrol.service.IPatrolDeviceService;
import com.inspect.patrol.service.IPatrolLinkageMessageService;
import com.inspect.patrol.service.IPatrolLinkagePosService;
import com.inspect.patrol.service.PatrolTaskService;
import com.inspect.patrol.service.WebsocketService;
import com.inspect.patrol.service.impl.PatrolLinkagePosServiceImpl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import static com.inspect.patrol.linkage.constain.LinkageContain.*;

@Component
public class ReceiveProcessor {
   private static final Logger logger = LoggerFactory.getLogger(ReceiveProcessor.class);
   @Autowired
   private IPatrolLinkageMessageService iPatrolLinkageMessageService;
   @Value("${patrol.video.linkage_task_name}")
   private String linkageTaskName;
   @Autowired
   private RedisService redisService;
   @Autowired
   private BasedataAreaService basedataAreaService;
   @Autowired
   private IPatrolDeviceService patrolDeviceService;
   @Autowired
   private IPatrolLinkagePosService patrolLinkagePosService;
   @Autowired
   private PatrolTaskService patrolTaskService;
   @Autowired
   private PatrolLinkagePosServiceImpl patrolLinkagePosServiceImpl;
   @Autowired
   private NettyUdpClient nettyUdpClient;
   @Autowired
   private WebsocketService websocketService;
   @Autowired
   private LinkageNotify linkageNotify;
   @Autowired
   private PatrolResultServiceImpl patrolResultService;

   public void parse(byte[] bytes) throws Exception {
      String type = this.parseFileType(bytes);
      System.out.println("====================接收到联动类型：" + type);
      byte var4 = -1;
      switch(type.hashCode()) {
      case 1663:
         if(type.equals("43")) {
            var4 = 0;
         }
         break;
      case 1696:
         if(type.equals("55")) {
            var4 = 1;
         }
      }

      switch(var4) {
      case 0:
         System.out.println("====================接收到联动资源文件");
         this.parseLinkageInfo(bytes);
         break;
      case 1:
         System.out.println("====================接收到联动信号");
         LinkageSignByte linkageSignByte = new LinkageSignByte(bytes);
         LinkageSignEntity linkageSignEntity = linkageSignByte.toLinkageSignEntity();
         PatrolLinkagePos patrolLinkagePos = this.patrolLinkagePosServiceImpl.selectPatrolLinkagePos(linkageSignEntity);
         List<LinkageTaskInfo> linkageTaskInfos = this.patrolDeviceService.selectPatrolDeviceList(((PatrolLinkageStrategy)patrolLinkagePos.getPatrolLinkageStrategies().get(0)).getPatrolLinkageStrategyRefs());
         boolean confirm = this.videoConfirm(patrolLinkagePos, linkageTaskInfos);
         if(confirm) {
            return;
         }

         this.redisService.redisTemplate.opsForList().leftPush("REDIS_LINKAGE_QUEUE", JSONObject.toJSONString(patrolLinkagePos));
         break;
      default:
         throw new ServiceException("帧类型解析异常");
      }

   }

   public void parseLinkageInfo(byte[] bytes) throws Exception {
      DeviceInfoFrame deviceInfoFrame = new DeviceInfoFrame();
      String content = deviceInfoFrame.parse(bytes);
      if(!StringUtils.isEmpty(content)) {
         List<IBlock> blocks = CimeProcessor.parse(content, DeviceInfoBlock.class);
         this.patrolLinkagePosService.insertPatrolLinkagePos(blocks);
         this.iPatrolLinkageMessageService.insertPatrolLinkageMessage("0", content);
         this.sendSuccess();
      }
   }

   public void parseLinkageSignal(PatrolLinkagePos patrolLinkagePos) throws Exception {
      List<LinkageTaskInfo> linkageTaskInfos = this.patrolDeviceService.selectPatrolDeviceList(((PatrolLinkageStrategy)patrolLinkagePos.getPatrolLinkageStrategies().get(0)).getPatrolLinkageStrategyRefs());
      String taskId = this.createTaskAndStopCurrent(linkageTaskInfos);
      PopupData popupData = this.combinePopup(linkageTaskInfos, taskId);
      popupData.setPatrolLinkagePos(patrolLinkagePos);
      this.sendByWebsocket(popupData);
      this.iPatrolLinkageMessageService.insertPatrolLinkageMessage("0", JSONObject.toJSONString(patrolLinkagePos));
   }

   public boolean videoConfirm(PatrolLinkagePos patrolLinkagePos, List<LinkageTaskInfo> linkageTaskInfos) throws Exception {
      PatrolLinkageStrategy patrolLinkageStrategy = patrolLinkagePos.getPatrolLinkageStrategies().get(0);
      if("2".equals(patrolLinkageStrategy.getTriggerSignalType()) && LinkageDeviceType.SIGNAL.getName().equals(patrolLinkagePos.getLinkageSignal()) && this.redisService.hasKey(REDIS_LINKAGE_QUEUE_NOW)) {
         logger.info("==================一键顺控遥信开始！");
         (new Thread(() -> {
            boolean stop = false;
            int index = 0;
            int maxExpire = 300;
            if(this.redisService.hasKey(REDIS_LINKAGE_SIGNAL_EXPIRE)) {
               maxExpire = this.redisService.getCacheObject(REDIS_LINKAGE_SIGNAL_EXPIRE);
            }

            while(!this.redisService.hasKey(REDIS_LINKAGE_CONFIRM_ACTION_RESULT)) {
               if(!stop) {
                  stop = true;
                  this.patrolTaskService.updateCameraPatrolTaskExecRecordState(linkageTaskInfos.get(0).getPatrolDeviceCode(), "4");
               }

               try {
                  Thread.sleep(1000L);
                  ++index;
                  if(index == maxExpire) {
                     logger.info("==================一键顺控遥信超时！");
                     return;
                  }
               } catch (InterruptedException var9) {
                  ;
               }
            }

            Object cacheObject = this.redisService.getCacheObject(REDIS_LINKAGE_CONFIRM_ACTION_RESULT);
            this.redisService.deleteObject(REDIS_LINKAGE_CONFIRM_ACTION_RESULT);

            try {
               PopupData popupData = (PopupData)JSONObject.parseObject((String)this.redisService.redisTemplate.opsForValue().get(REDIS_LINKAGE_TASK_DATA), PopupData.class);
               popupData.setPatrolLinkagePos(patrolLinkagePos);
               this.redisService.redisTemplate.opsForValue().set(REDIS_LINKAGE_TASK_DATA, JSONObject.toJSONString(popupData));
               this.linkageNotify.notify(String.valueOf(cacheObject));
            } catch (Exception var8) {
               var8.printStackTrace();
               throw new ServiceException("一键顺控遥信异常");
            }
         })).start();
         return true;
      } else {
         return false;
      }
   }

   public void sendSuccess() throws Exception {
      List<byte[]> list = new ArrayList();
      list.add("ok".getBytes());
      this.nettyUdpClient.sendMessage(list);
   }

   private PopupData combinePopup(List<LinkageTaskInfo> linkageTaskInfos, String taskId) {
      List<PopupInfoData> popupInfoDataList = new ArrayList();
      String eqpbookId = null;

      for(int i = 0; i < linkageTaskInfos.size(); ++i) {
         LinkageTaskInfo linkageTaskInfo = (LinkageTaskInfo)linkageTaskInfos.get(i);
         if(!linkageTaskInfo.getEqpBookId().equals(eqpbookId)) {
            eqpbookId = linkageTaskInfo.getEqpBookId();
            popupInfoDataList.add(new PopupInfoData(linkageTaskInfo));
         }

         PopupInfoData popupInfoData = (PopupInfoData)popupInfoDataList.get(popupInfoDataList.size() - 1);
         popupInfoData.getList().add(linkageTaskInfo);
         popupInfoData.setTaskId(taskId);
      }

      PopupData popupData = new PopupData();
      popupData.setPopupInfoDataList(popupInfoDataList);
      return popupData;
   }

   private String parseFileType(byte[] bytes) {
      byte[] typ = Arrays.copyOfRange(bytes, 4, 5);

      try {
         return HexUtils.binary(typ, 16);
      } catch (Exception var4) {
         throw new ServiceException("没有此报文类型！");
      }
   }

   public void sendByWebsocket(PopupData popupData) {
      if(!"0".equals(this.redisService.getCacheObject(LinkageContain.KEY_LINKAGE_ACTION_POPUP))) {
         this.redisService.redisTemplate.opsForValue().set(REDIS_LINKAGE_TASK_DATA, JSONObject.toJSONString(popupData));
         JSONObject params = (new JSONObject()).fluentPut("event", LinkageContain.WEBSOCKET_LINKAGE_INFO).fluentPut("data", popupData.getPopupInfoDataList());
         this.websocketService.parseMessage(params.toJSONString());
      }
   }

   private String createTaskAndStopCurrent(List<LinkageTaskInfo> linkageTaskInfos) {
      Map<String, String> map = this.patrolResultService.selectBasedataStation();
      String stationCode = "1";
      String stationName = "500kv";
      if(map != null && map.size() > 0) {
         stationCode = (String)map.get("station_no");
         stationName = (String)map.get("station_name");
      }

      String patroldeviceCode = null;
      Iterator var6 = linkageTaskInfos.iterator();

      while(var6.hasNext()) {
         LinkageTaskInfo linkageTaskInfo = (LinkageTaskInfo)var6.next();
         if(linkageTaskInfo.getPatrolDeviceCode() != null && !linkageTaskInfo.getPatrolDeviceCode().equals(patroldeviceCode)) {
            patroldeviceCode = linkageTaskInfo.getPatrolDeviceCode();
            this.patrolTaskService.updateCameraPatrolTaskExecRecordState(patroldeviceCode, "3");
         }
      }

      LinkagePatrolTask linkagePatrolTask = new LinkagePatrolTask();
      linkagePatrolTask.setStationCode(stationCode);
      linkagePatrolTask.setStationName(stationName);
      linkagePatrolTask.setTaskName(((LinkageTaskInfo)linkageTaskInfos.get(0)).getPatrolDeviceName() + this.linkageTaskName);
      linkageTaskInfos.forEach((item) -> {
         linkagePatrolTask.addPrevPoint(item);
      });
      AjaxResult ajaxResult = this.patrolTaskService.add(JSONObject.toJSONString(linkagePatrolTask));
      return String.valueOf(ajaxResult.get("msg"));
   }

   private JSONObject queryStation() {
      AjaxResult ajaxResult = this.basedataAreaService.list((new JSONObject()).fluentPut("areaType", "station"));
      JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(ajaxResult));
      return jsonObject.getJSONArray("data").getJSONObject(0);
   }
}
