package com.jiayue.ipfcst.dataexchange.tunnelworker.workassist.cdt;

import com.alibaba.fastjson.JSON;
import com.jiayue.ipfcst.common.data.constant.enums.TunnelStatus;
import com.jiayue.ipfcst.dataexchange.tunnelworker.senders.iml.CdtRtuDataSender;
import lombok.Data;
import wei.yigulu.cdt.cdtframe.*;

import java.util.*;

/**
 * cdt 数据发送器的实现类
 *
 * @author: xiuwei
 * @version:
 */
@Data
public class MyCDTDataTransmitter extends AbstractCDTDataTransmitter {

  /**
   * 构造方法
   *
   * @param cdtRtuDataSender cdt发送实体
   */
  public MyCDTDataTransmitter(CdtRtuDataSender cdtRtuDataSender) {
    this.cdtRtuDataSender = cdtRtuDataSender;
  }

  private CdtRtuDataSender cdtRtuDataSender;

  /**
   * 重要遥测  数据
   */
  Map<Integer, Integer> importantYc = new HashMap<>();
  /**
   * 次要遥测  数据
   */
  Map<Integer, Integer> secondYc = new HashMap<>();

  /**
   * 一般遥测  数据
   */
  Map<Integer, Integer> commonYc = new HashMap<>();


  /**
   * 遥信数据
   */
  Map<Integer, Boolean> yx = new HashMap<>();


  @Override
  public List<CDTFrameBean> transmitImportantYc() {
    return buildYc(CDTType.IMPORTANTYC, importantYc);
  }

  @Override
  public List<CDTFrameBean> transmitSecondYc() {
    return buildYc(CDTType.SECONDYC, importantYc);
  }

  @Override
  public List<CDTFrameBean> transmitCommonYc() {
    return buildYc(CDTType.COMMONYC, importantYc);
  }

  @Override
  public List<CDTFrameBean> transmitYx() {
    log.info("遥信数据：" + JSON.toJSONString(this.yx));
    List<CDTFrameBean> frameList = null;
    try {
      frameList = new ArrayList<>(1);
      Set<Integer> yxKey = yx.keySet();
      if (yx == null || yx.size() == 0) {
        return frameList;
      }
      int min = Collections.min(yxKey);
      int max = Collections.max(yxKey);
      if (min % 32 != 0) {
        min = min / 32 * 32;
      }
      List<BaseDateType> dataTypeList = new ArrayList<>();
      Map<Integer, Boolean> val;
      BooleanDataType booleanDataType;
      for (int i = 0; 32 * i <= max; i++) {
        val = new HashMap<>(32);
        for (int j = 0; j < 32; j++) {
          if (yxKey.contains(min + 32 * i + j)) {
            val.put(min + 32 * i + j, this.yx.get(min + 32 * i + j));
          } else {
            val.put(min + 32 * i + j, false);
          }
        }
        booleanDataType = new BooleanDataType(val);
        dataTypeList.add(booleanDataType);
      }
      CDTFrameBean cdtFrameBean = new CDTFrameBean(dataTypeList);
      frameList.add(cdtFrameBean);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return frameList;
  }


  /**
   * 构建遥测数据帧数组
   *
   * @param cdtType
   * @param yc
   * @return cdt的数据帧集合
   */
  private List<CDTFrameBean> buildYc(CDTType cdtType, Map<Integer, Integer> yc) {
    log.info("次要遥测：" + JSON.toJSONString(this.secondYc));
    log.info("一般遥测：" + JSON.toJSONString(this.commonYc));
    log.info("重要遥测：" + JSON.toJSONString(this.importantYc));
    List<Integer> ycKey = new ArrayList<>(yc.keySet());
    Collections.sort(ycKey);
    int f;
    Map<Integer, Integer> val;
    List<CDTFrameBean> frameList = new ArrayList<>(1);
    List<BaseDateType> dataTypeList = new ArrayList<>();
    IntegerDataType integerDataType;
    for (int i = 0; i < ycKey.size(); ) {
      val = new HashMap<>(2);
      f = ycKey.get(i);
      if (f % 2 == 0) {
        val.put(f, yc.get(f));
        if (ycKey.contains(f + 1)) {
          val.put(f + 1, yc.get(f + 1));
          i += 2;
        } else {
          val.put(f + 1, 0);
          i += 1;
        }
      } else {
        val.put(f - 1, 0);
        val.put(f, yc.get(f));
        i += 1;
      }
      integerDataType = new IntegerDataType(val, null);
      dataTypeList.add(integerDataType);
    }
    CDTFrameBean cdtFrameBean = new CDTFrameBean(dataTypeList);
    cdtFrameBean.setCdtType(cdtType);
    frameList.add(cdtFrameBean);
    return frameList;
  }

  @Override
  public void connected() {
    this.cdtRtuDataSender.setTunnelStatus(TunnelStatus.LISTENSERIALSUCCESS);
  }


  @Override
  public void disconnected() {
    this.cdtRtuDataSender.setTunnelStatus(TunnelStatus.LISTENSERIALFAIL);
  }
}
