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

import com.jiayue.ipfcst.common.data.constant.enums.TunnelStatus;
import com.jiayue.ipfcst.common.data.entity.gathertunnelinfo.GatherModbusRtuTunnelInfo;
import com.jiayue.ipfcst.dataexchange.exception.DataExchangeException;
import com.jiayue.ipfcst.dataexchange.tunnelworker.BaseProtocolTunnel;
import com.jiayue.ipfcst.dataexchange.tunnelworker.workassist.SingleThreadPoolExecutorUtil;
import wei.yigulu.modbus.domain.FunctionCode;
import wei.yigulu.modbus.netty.ModbusRtuMasterBuilder;
import wei.yigulu.purejavacomm.PureJavaCommChannelConfig;

/**
 * modbus RTU 采集通道
 *
 * @author: xiuwei
 * @version: 3.0
 */
public class ModbusRtuDataGather extends AbstractModbusDataGather<GatherModbusRtuTunnelInfo, ModbusRtuDataGather.ModbusMaster> {


  private int exceptionNum = 0;

  /**
   * 构造方法
   *
   * @param gatherModbusRtuTunnelInfo 通道信息
   */
  public ModbusRtuDataGather(final GatherModbusRtuTunnelInfo gatherModbusRtuTunnelInfo) {
    super(gatherModbusRtuTunnelInfo);
  }

  @Override
  public ModbusRtuDataGather buildTunnel() throws DataExchangeException {
    ModbusMaster builder = new ModbusMaster(this.tunnelInfo.getSerialName());
    builder.setBaudRate(tunnelInfo.getBaudRate());
    builder.setDataBits(PureJavaCommChannelConfig.Databits.valueOf(tunnelInfo.getDataBits()));
    builder.setStopBits(PureJavaCommChannelConfig.Stopbits.valueOf(tunnelInfo.getStopBits()));
    builder.setParity(PureJavaCommChannelConfig.Paritybit.valueOf(tunnelInfo.getParity()));
    builder.setLog(this.log);
    setProtocolBuilder(builder);
    setSlaveId(this.tunnelInfo.getSlaveId());
    setFunctionCode(FunctionCode.valueOf(this.tunnelInfo.getFunctionCode()));
    this.parseGatherDataPoint();
    protocolTunnelContainer.addTunnel(this);
    this.setTunnelStatus(TunnelStatus.BUILT);
    log.info("成功创建ModbusRTUMaster通道对象：{}", this.tunnelInfo.getTunnelName());
    return this;
  }


  @Override
  public ModbusRtuDataGather startTunnel() throws DataExchangeException {
    log.info("modbus RTU master {} 通道开始连接", getTunnelInfo().getTunnelName());
    protocolTunnelContainer.addUpdateDateTask(this);
    try {
      SingleThreadPoolExecutorUtil.executeBySingleThreadExecutor(() -> {
        try {
          this.protocolBuilder.create();
          log.error("Modbus Rtu Master  创建通道失败");
          setTunnelStatus(TunnelStatus.LISTENSERIALFAIL);
        } catch (Exception e) {
          log.error("Modbus Rtu Master  创建通道失败", e);
          setTunnelStatus(TunnelStatus.LISTENSERIALFAIL);
        }
      });
    } catch (Exception e) {
      log.error("Modbus Rtu Master 创建通道失败", e);
      setTunnelStatus(TunnelStatus.LISTENSERIALFAIL);
      throw new DataExchangeException(10007, "Modbus Rtu Master创建通道失败");
    }
    if (!TunnelStatus.LISTENSERIALFAIL.equals(getTunnelStatus())) {
      setTunnelStatus(TunnelStatus.LISTENSERIALSUCCESS);
    }
    return this;
  }


  @Override
  public void getDataFromProtocol() throws DataExchangeException {
    try {
      super.getDataFromProtocol();
      this.consecutiveExceptions=0;
      this.setTunnelStatus(TunnelStatus.LISTENSERIALSUCCESS);
    }catch (Exception e){
      this.consecutiveExceptions++;
      if(consecutiveExceptions>10) {
        this.setTunnelStatus(TunnelStatus.LISTENSERIALSUCCESSANDCOMMERROR);
      }
    }
  }

  @Override
  public BaseProtocolTunnel tunnelStop() throws DataExchangeException {
    if (this.protocolBuilder != null) {
      this.protocolBuilder.stop();
    }
    log.info("关闭 Modbus Rtu Master 通道 {}", this.tunnelInfo.getTunnelName());
    return super.tunnelStop();
  }


  private void setExceptionNum(int o) {
    if (o == 0) {
      this.exceptionNum = 0;
    }
    if (o == 1) {
      this.exceptionNum++;
    }
    if (this.exceptionNum >= 10) {
      //this.setTunnelStatus();
    }

  }

  class ModbusMaster extends ModbusRtuMasterBuilder {

    public ModbusMaster(String commPortId) {
      super(commPortId);
    }

    @Override
    public void connected() {
    }

    @Override
    public void disconnected() {
    }
  }

}


