package com.jiayue.ipfcst.dataexchange.tunnelworker.senders.iml;

import com.alibaba.fastjson.JSON;
import com.jiayue.ipfcst.common.data.entity.BaseTunnelInfo;
import com.jiayue.ipfcst.common.data.entity.ProtocolDataType;
import com.jiayue.ipfcst.common.data.entity.ProtocolSenderDataPoint;
import com.jiayue.ipfcst.dataexchange.dataprocesser.datagainerhandler.BaseDataGainer;
import com.jiayue.ipfcst.dataexchange.dataprocesser.datagainerhandler.DataGainerBuilder;
import com.jiayue.ipfcst.dataexchange.exception.DataExchangeException;
import com.jiayue.ipfcst.dataexchange.tunnelworker.BaseProtocolTunnel;
import com.jiayue.ipfcst.dataexchange.tunnelworker.senders.DataSenderInterface;
import lombok.Getter;
import lombok.Setter;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import wei.yigulu.modbus.domain.ModbusSlaveDataContainer;
import wei.yigulu.modbus.domain.datatype.BooleanModbusDataInRegister;
import wei.yigulu.modbus.domain.datatype.ModbusDataTypeEnum;
import wei.yigulu.modbus.domain.datatype.NumericModbusData;
import wei.yigulu.netty.BaseProtocolBuilder;

import java.math.BigDecimal;
import java.util.*;

/**
 * 抽象的modbus数据获取
 *
 * @author: xiuwei
 * @version:
 */
@Setter
@Getter
public abstract class AbstractModbusDataSender<T extends BaseTunnelInfo, E extends BaseProtocolBuilder> extends BaseProtocolTunnel<T> implements DataSenderInterface {

  protected E protocolBuilder;
  /**
   * 通道点位  ---- 点位对象
   */
  Map<Integer, ProtocolSenderDataPoint> dataPointMap;
  /**
   * 遥测点位数据构建器集合
   */
  Map<Integer, BaseDataGainer<Number>> ycDataPoints = new HashMap<>();
  /**
   * 遥信点位数据构建器集合
   */
  Map<Integer, BaseDataGainer<Boolean>> yxDataPoints = new HashMap<>();
  ModbusSlaveDataContainer modbusSlaveDataContainer;
  Integer slaveId;
  /**
   * 0: 线圈   1：寄存器
   */
  private int functionFlag;


  /**
   * 顶层的构造方法
   *
   * @param tunnelInfo 通道信息
   */
  public AbstractModbusDataSender(T tunnelInfo) {
    super(tunnelInfo);
  }

  @Override
  public void updateData2Protocol() throws DataExchangeException {
    HashMap<Integer, String> dataMap = new HashMap<>();
    if (functionFlag == 1) {
      dataPointMap.forEach((k, v) -> {
        if (ModbusDataTypeEnum.A16 == v.getProtocolPointType().getModbusDataType() && yxDataPoints.containsKey(v.getId())) {
          BooleanModbusDataInRegister booleanModbusDataInRegister = new BooleanModbusDataInRegister();
          try {
            Boolean bValue = yxDataPoints.get(v.getId()).getData();
            dataMap.put(k, bValue.toString());
            booleanModbusDataInRegister.setValue(0, bValue);
          } catch (DataExchangeException e) {
            e.printStackTrace();
          }
          modbusSlaveDataContainer.setRegister(slaveId, k, booleanModbusDataInRegister);
        } else if (ModbusDataTypeEnum.A16 != v.getProtocolPointType().getModbusDataType() && ycDataPoints.containsKey(v.getId())) {
          try {
            Number nValue = BigDecimal.valueOf(ycDataPoints.get(v.getId()).getData().doubleValue());
            dataMap.put(k, nValue.toString());
            modbusSlaveDataContainer.setRegister(slaveId, k, ((NumericModbusData) (v.getProtocolPointType().getModbusDataType().getObject())).setValue(BigDecimal.valueOf(nValue.doubleValue())));
          } catch (DataExchangeException e) {
            e.printStackTrace();
          }
        }
      });
    } else {
      dataPointMap.forEach((k, v) ->
        {
          if (yxDataPoints.containsKey(v.getId())) {
            Boolean bValue = false;
            try {
              bValue = yxDataPoints.get(v.getId()).getData();
            } catch (DataExchangeException e) {
              e.printStackTrace();
            }
            dataMap.put(k, bValue.toString());
            modbusSlaveDataContainer.setCoil(slaveId, k, bValue);
          }
        }
      );
    }
    log.info(JSON.toJSONString(dataMap));
  }


  @Override
  public void parseGatherDataPoint() throws DataExchangeException {
    this.log.info("解析该通道下所管理的点位");
    List<ProtocolSenderDataPoint> dataPoints = this.tunnelInfo.getDataPoints();
    Map<Integer, ProtocolSenderDataPoint> dataPointMap = new HashMap<>();
    if (dataPoints == null || dataPoints.size() == 0) {
      this.dataPointMap = dataPointMap;
      return;
    }
    Collections.sort(dataPoints, Comparator.comparingInt(ProtocolSenderDataPoint::getProtocolPointNo));
    int i = 0;
    for (ProtocolSenderDataPoint d : dataPoints) {
      dataPointMap.put(i, d);
      if (d.getProtocolPointType() == ProtocolDataType.A) {
        yxDataPoints.put(d.getId(), DataGainerBuilder.build(d));
      } else {
        ycDataPoints.put(d.getId(), DataGainerBuilder.build(d));
      }
      i += d.getProtocolPointType().getModbusDataType().getOccupiedRegister();
    }
    this.dataPointMap = dataPointMap;
    this.log.info("解析该通道下所管理的点位完成");
  }
}
