package com.jiayue.ipfcst.dataexchange.service;

import com.jiayue.ipfcst.common.core.exception.BusinessException;
import com.jiayue.ipfcst.common.core.util.SpringContextHolder;
import com.jiayue.ipfcst.common.data.constant.enums.TunnelType;
import com.jiayue.ipfcst.common.data.entity.*;
import com.jiayue.ipfcst.common.data.entity.gathertunnelinfo.*;
import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.Sender104TcpTunnelInfo;
import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.SenderCdtRtuTunnelInfo;
import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.SenderModbusRtuTunnelInfo;
import com.jiayue.ipfcst.common.data.entity.sendertunnelinfo.SenderModbusTcpTunnelInfo;
import com.jiayue.ipfcst.console.service.ElectricFieldService;
import com.jiayue.ipfcst.console.service.WeatherStationInfoService;
import com.jiayue.ipfcst.console.service.WindTowerInfoService;
import com.jiayue.ipfcst.dataexchange.repository.ProtocolGatherDataPointRepository;
import com.jiayue.ipfcst.dataexchange.repository.ProtocolSenderDataPointRepository;
import com.jiayue.ipfcst.dataexchange.repository.gathertunnelrepository.*;
import com.jiayue.ipfcst.dataexchange.repository.sendertunnelrepository.Sender104TcpTunnelRepository;
import com.jiayue.ipfcst.dataexchange.repository.sendertunnelrepository.SenderCdtRtuTunnelRepository;
import com.jiayue.ipfcst.dataexchange.repository.sendertunnelrepository.SenderModbusRtuTunnelRepository;
import com.jiayue.ipfcst.dataexchange.repository.sendertunnelrepository.SenderModbusTcpTunnelRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 对通道信息进行操作的方法
 *
 * @author 修唯xiuwei
 * @version 3.0
 */
@Service
public class TunnelInfoService {

	private final Gather104TcpTunnelRepository gather104TcpTunnelRepository;
	private final Sender104TcpTunnelRepository sender104TcpTunnelRepository;
	private final GatherModbusTcpTunnelRepository gatherModbusTcpTunnelRepository;
	private final SenderModbusTcpTunnelRepository senderModbusTcpTunnelRepository;
	private final GatherModbusRtuTunnelRepository gatherModbusRtuTunnelRepository;
	private final SenderModbusRtuTunnelRepository senderModbusRtuTunnelRepository;
	private final GatherCdtRtuTunnelRepository gatherCdtRtuTunnelRepository;
	private final SenderCdtRtuTunnelRepository senderCdtRtuTunnelRepository;

	private final FileParseTunnelRepository fileParseTunnelRepository;
	private final ProtocolGatherDataPointRepository protocolGatherDataPointRepository;
	private final ProtocolSenderDataPointRepository protocolSenderDataPointRepository;
	private final ProtocolGatherDataPointService protocolGatherDataPointService;
	private final ProtocolSenderDataPointService protocolSenderDataPointService;
	private final ElectricFieldService electricFieldService;
	private final WeatherStationInfoService weatherStationInfoService;
	private final WindTowerInfoService windTowerInfoService;
	private final GatherModbusRtuWithTcpServerTunnelRepository gatherModbusRtuWithTcpServerTunnelRepository;
  private final GatherModbusRtuWithTcpClientTunnelRepository gatherModbusRtuWithTcpClientTunnelRepository;

	/**
	 * Tunnel info service
	 *  @param gather104TcpTunnelRepository      gather 104 tcp tunnel repository
	 * @param sender104TcpTunnelRepository      sender 104 tcp tunnel repository
   * @param gatherModbusTcpTunnelRepository   gather modbus tcp tunnel repository
   * @param senderModbusTcpTunnelRepository   sender modbus tcp tunnel repository
   * @param gatherModbusRtuTunnelRepository   gather modbus rtu tunnel repository
   * @param senderModbusRtuTunnelRepository   sender modbus rtu tunnel repository
   * @param gatherCdtRtuTunnelRepository      gather cdt rtu tunnel repository
   * @param senderCdtRtuTunnelRepository      sender cdt rtu tunnel repository
   * @param fileParseTunnelRepository         文件解析通道仓储
   * @param protocolGatherDataPointRepository
   * @param protocolSenderDataPointRepository
   * @param protocolGatherDataPointService
   * @param protocolSenderDataPointService
   * @param electricFieldService
   * @param weatherStationInfoService
   * @param windTowerInfoService
   * @param gatherModbusRtuWithTcpServerTunnelRepository
   * @param gatherModbusRtuWithTcpClientTunnelRepository
   *
	 */
	@Autowired
	public TunnelInfoService(Gather104TcpTunnelRepository gather104TcpTunnelRepository, Sender104TcpTunnelRepository sender104TcpTunnelRepository,
    GatherModbusTcpTunnelRepository gatherModbusTcpTunnelRepository, SenderModbusTcpTunnelRepository senderModbusTcpTunnelRepository,
    GatherModbusRtuTunnelRepository gatherModbusRtuTunnelRepository, SenderModbusRtuTunnelRepository senderModbusRtuTunnelRepository,
    GatherCdtRtuTunnelRepository gatherCdtRtuTunnelRepository, SenderCdtRtuTunnelRepository senderCdtRtuTunnelRepository,
    FileParseTunnelRepository fileParseTunnelRepository, ProtocolGatherDataPointRepository protocolGatherDataPointRepository,
    ProtocolSenderDataPointRepository protocolSenderDataPointRepository, ProtocolGatherDataPointService protocolGatherDataPointService,
    ProtocolSenderDataPointService protocolSenderDataPointService, ElectricFieldService electricFieldService,
    WeatherStationInfoService weatherStationInfoService, WindTowerInfoService windTowerInfoService,
    GatherModbusRtuWithTcpServerTunnelRepository gatherModbusRtuWithTcpServerTunnelRepository,
    GatherModbusRtuWithTcpClientTunnelRepository gatherModbusRtuWithTcpClientTunnelRepository) {
		this.gather104TcpTunnelRepository = gather104TcpTunnelRepository;
		this.sender104TcpTunnelRepository = sender104TcpTunnelRepository;
		this.gatherModbusTcpTunnelRepository = gatherModbusTcpTunnelRepository;
		this.senderModbusTcpTunnelRepository = senderModbusTcpTunnelRepository;
		this.gatherModbusRtuTunnelRepository = gatherModbusRtuTunnelRepository;
		this.senderModbusRtuTunnelRepository = senderModbusRtuTunnelRepository;
		this.gatherCdtRtuTunnelRepository = gatherCdtRtuTunnelRepository;
		this.senderCdtRtuTunnelRepository = senderCdtRtuTunnelRepository;
		this.fileParseTunnelRepository = fileParseTunnelRepository;
		this.protocolGatherDataPointRepository = protocolGatherDataPointRepository;
		this.protocolSenderDataPointRepository = protocolSenderDataPointRepository;
		this.protocolGatherDataPointService = protocolGatherDataPointService;
		this.protocolSenderDataPointService = protocolSenderDataPointService;
		this.electricFieldService = electricFieldService;
		this.weatherStationInfoService = weatherStationInfoService;
		this.windTowerInfoService = windTowerInfoService;
    this.gatherModbusRtuWithTcpServerTunnelRepository = gatherModbusRtuWithTcpServerTunnelRepository;
    this.gatherModbusRtuWithTcpClientTunnelRepository = gatherModbusRtuWithTcpClientTunnelRepository;
  }
	// @Autowired ElectricFieldService electricFieldService;

	/**
	 * 获取所有的通道信息 所有的
	 *
	 * @return BaseTunnelInfo all tunnel
	 */
	public List<BaseTunnelInfo> getAllTunnel() {
		List<BaseTunnelInfo> baseTunnelInfos = new ArrayList<>();
		baseTunnelInfos.addAll(gather104TcpTunnelRepository.findAll());
		baseTunnelInfos.addAll(sender104TcpTunnelRepository.findAll());
		baseTunnelInfos.addAll(gatherModbusTcpTunnelRepository.findAll());
		baseTunnelInfos.addAll(senderModbusTcpTunnelRepository.findAll());
		baseTunnelInfos.addAll(gatherModbusRtuTunnelRepository.findAll());
		baseTunnelInfos.addAll(senderModbusRtuTunnelRepository.findAll());
		baseTunnelInfos.addAll(gatherCdtRtuTunnelRepository.findAll());
		baseTunnelInfos.addAll(senderCdtRtuTunnelRepository.findAll());
		baseTunnelInfos.addAll(fileParseTunnelRepository.findAll());
		baseTunnelInfos.addAll(gatherModbusRtuWithTcpClientTunnelRepository.findAll());
    baseTunnelInfos.addAll(gatherModbusRtuWithTcpServerTunnelRepository.findAll());
		baseTunnelInfos.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
		return baseTunnelInfos;
	}


	/**
	 * 得到所有采集通道
	 *
	 * @return 通道信息集合
	 */
	public List<BaseTunnelInfo> getAllGatherTunnel() {
		List<BaseTunnelInfo> baseTunnelInfos = new ArrayList<>();
		baseTunnelInfos.addAll(gather104TcpTunnelRepository.findAll());
		baseTunnelInfos.addAll(gatherModbusTcpTunnelRepository.findAll());
		baseTunnelInfos.addAll(gatherModbusRtuTunnelRepository.findAll());
		baseTunnelInfos.addAll(gatherCdtRtuTunnelRepository.findAll());
		baseTunnelInfos.addAll(fileParseTunnelRepository.findAll());
    baseTunnelInfos.addAll(gatherModbusRtuWithTcpClientTunnelRepository.findAll());
    baseTunnelInfos.addAll(gatherModbusRtuWithTcpServerTunnelRepository.findAll());
		baseTunnelInfos.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
		return baseTunnelInfos;
	}

	/**
	 * 得到所有转发隧道
	 *
	 * @return BaseTunnelInfo 通道信息集合
	 */
	public List<BaseTunnelInfo> getAllSenderTunnel() {
		List<BaseTunnelInfo> baseTunnelInfos = new ArrayList<>();
		baseTunnelInfos.addAll(sender104TcpTunnelRepository.findAll());
		baseTunnelInfos.addAll(senderModbusTcpTunnelRepository.findAll());
		baseTunnelInfos.addAll(senderModbusRtuTunnelRepository.findAll());
		baseTunnelInfos.addAll(senderCdtRtuTunnelRepository.findAll());
		baseTunnelInfos.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
		return baseTunnelInfos;
	}
  /**
   * 保存或者修改通道信息
   */
  public BaseTunnelInfo saveOrUpdateTunnelInfo(BaseTunnelInfo baseTunnelInfo) {
    baseTunnelInfo.setStationCode(SpringContextHolder.getBean(ElectricFieldService.class).get().getStationCode());
    baseTunnelInfo.setDataPoints(null);
    switch (baseTunnelInfo.getTunnelType()) {
      case IEC104TCPMASTER:
        return gather104TcpTunnelRepository.save((Gather104TcpTunnelInfo)baseTunnelInfo);
      case MODBUSRTUMASTER:
        return gatherModbusRtuTunnelRepository.save((GatherModbusRtuTunnelInfo)baseTunnelInfo);
      case MODBUSTCPMASTER:
        return gatherModbusTcpTunnelRepository.save((GatherModbusTcpTunnelInfo)baseTunnelInfo);
      case MODBUSTCPSLAVE:
        return senderModbusTcpTunnelRepository.save((SenderModbusTcpTunnelInfo)baseTunnelInfo);
      case MODBUSRTUSLAVE:
        return senderModbusRtuTunnelRepository.save((SenderModbusRtuTunnelInfo)baseTunnelInfo);
      case CDTRTUSLAVE:
        return senderCdtRtuTunnelRepository.save((SenderCdtRtuTunnelInfo)baseTunnelInfo);
      case CDTRTUMASTER:
        return gatherCdtRtuTunnelRepository.save((GatherCdtRtuTunnelInfo)baseTunnelInfo);
      case IEC104TCPSLAVE:
        return sender104TcpTunnelRepository.save((Sender104TcpTunnelInfo)baseTunnelInfo);
      case FILEPARSE:
        return fileParseTunnelRepository.save((FileParseTunnelInfo)baseTunnelInfo);
      case TCPSERVERASMODBUSMASTER:
        return gatherModbusRtuWithTcpServerTunnelRepository.save((GatherModbusRtuWithTcpServerTunnelInfo)baseTunnelInfo);
      case TCPCLIENTASMODBUSMASTER:
        return gatherModbusRtuWithTcpClientTunnelRepository.save((GatherModbusRtuWithTcpClientTunnelInfo)baseTunnelInfo);
    }
    return null;
  }
	/**
	 * 获取到所有的 104tcp采集通道信息
	 *
	 * @return Gather104TcpTunnelInfo all gather 104 tcp tunnel
	 */
	public List<Gather104TcpTunnelInfo> getAllGather104TcpTunnel() {
		List<Gather104TcpTunnelInfo> gather104TcpTunnelInfoList = gather104TcpTunnelRepository.findAll();
		gather104TcpTunnelInfoList.sort(Comparator.comparing(Gather104TcpTunnelInfo::getTunnelName));
		return gather104TcpTunnelInfoList;
	}

	/**
	 * 得到所有文件解析通道
	 * 获取到所有的 文件采集通道信息
	 *
	 * @return FileParseTunnelInfo 所有的文件解析通道
	 */
	public List<FileParseTunnelInfo> getAllFileParseTunnel() {
		List<FileParseTunnelInfo> fileParseTunnelInfoList = fileParseTunnelRepository.findAll();
		fileParseTunnelInfoList.sort(Comparator.comparing(FileParseTunnelInfo::getTunnelName));
		return fileParseTunnelInfoList;
	}

	/**
	 * 修改或保存文件解析通道
	 *
	 * @param fileParseTunnelInfo
	 * @return FileParseTunnelInfo 所有的文件解析通道
	 */
	public FileParseTunnelInfo saveOrUpdateFileParseTunnel(FileParseTunnelInfo fileParseTunnelInfo) {
		fileParseTunnelInfo.setStationCode(SpringContextHolder.getBean(ElectricFieldService.class).get().getStationCode());
		fileParseTunnelInfo.setDataPoints(null);
		fileParseTunnelInfo = fileParseTunnelRepository.save(fileParseTunnelInfo);
		return fileParseTunnelInfo;
	}

	/**
	 * 获取到符合要求的 104tcp采集通道信息
	 *
	 * @param gather104TcpTunnelInfo gather 104 tcp tunnel info
	 * @return Gather104TcpTunnelInfo gather 104 tcp tunnel
	 */
	public List<Gather104TcpTunnelInfo> getGather104TcpTunnel(Gather104TcpTunnelInfo gather104TcpTunnelInfo) {
		return gather104TcpTunnelRepository.findAll(Example.of(gather104TcpTunnelInfo));
	}

	/**
	 * 保存或者修改104Tcp通道信息
	 *
	 * @param gather104TcpTunnelInfo gather 104 tcp tunnel info
	 * @return Gather104TcpTunnelInfo gather 104 tcp tunnel info
	 */
	@Transactional(propagation = Propagation.SUPPORTS)
	public Gather104TcpTunnelInfo saveOrUpdateGather104TcpTunnel(Gather104TcpTunnelInfo gather104TcpTunnelInfo) {
		gather104TcpTunnelInfo.setStationCode(SpringContextHolder.getBean(ElectricFieldService.class).get().getStationCode());
		gather104TcpTunnelInfo.setDataPoints(null);
		return gather104TcpTunnelRepository.save(gather104TcpTunnelInfo);
	}


	/**
	 * 获取到所有的 104tcp转发通道信息
	 *
	 * @return Sender104TcpTunnelInfo all sender 104 tcp tunnel
	 */
	public List<Sender104TcpTunnelInfo> getAllSender104TcpTunnel() {
		List<Sender104TcpTunnelInfo> sender104TcpTunnelInfoList = sender104TcpTunnelRepository.findAll();
		sender104TcpTunnelInfoList.sort(Comparator.comparing(Sender104TcpTunnelInfo::getTunnelName));
		return sender104TcpTunnelInfoList;
	}


	/**
	 * 获取到所有的 Modbus tcp采集通道信息
	 *
	 * @return GatherModbusTcpTunnelInfo all gather modbus tcp tunnel
	 */
	public List<GatherModbusTcpTunnelInfo> getAllGatherModbusTcpTunnel() {
		List<GatherModbusTcpTunnelInfo> gatherModbusTcpTunnelInfoList = gatherModbusTcpTunnelRepository.findAll();
		gatherModbusTcpTunnelInfoList.sort(Comparator.comparing(GatherModbusTcpTunnelInfo::getTunnelName));
		return gatherModbusTcpTunnelInfoList;
	}



	/**
	 * 保存或者修改 Modbus tcp采集通道信息
	 *
	 * @param gatherModbusTcpTunnelInfo all gather modbus tcp tunnel
	 * @return GatherModbusTcpTunnelInfo all gather modbus tcp tunnel
	 */
	public GatherModbusTcpTunnelInfo saveOrUpdateGatherModbusTcpTunnel(GatherModbusTcpTunnelInfo gatherModbusTcpTunnelInfo) {
		gatherModbusTcpTunnelInfo.setStationCode(SpringContextHolder.getBean(ElectricFieldService.class).get().getStationCode());
		gatherModbusTcpTunnelInfo.setDataPoints(null);
		return gatherModbusTcpTunnelRepository.save(gatherModbusTcpTunnelInfo);
	}

  /**
   * 获取到所有的 modbus RTU 协议tcp server采集通道
   *
   * @return GatherModbusRtuWithTcpServerTunnelInfo all
   */
  public List<GatherModbusRtuWithTcpServerTunnelInfo> getAllGatherModbusRtuWithTcpServerTunnel() {
    List<GatherModbusRtuWithTcpServerTunnelInfo> gatherModbusRtuWithTcpServerTunnelInfoList = gatherModbusRtuWithTcpServerTunnelRepository.findAll();
    gatherModbusRtuWithTcpServerTunnelInfoList.sort(Comparator.comparing(GatherModbusRtuWithTcpServerTunnelInfo::getTunnelName));
    return gatherModbusRtuWithTcpServerTunnelInfoList;
  }

	/**
	 * 保存或者修改所有的 modbus RTU 协议tcp server采集通道
	 *
	 * @param gatherModbusRtuWithTcpServerTunnelInfo all gather modbus tcp tunnel
	 * @return GatherModbusTcpTunnelInfo all gather modbus tcp tunnel
	 */
	public GatherModbusRtuWithTcpServerTunnelInfo saveOrUpdateGatherModbusRtuWithTcpServerTunnel(GatherModbusRtuWithTcpServerTunnelInfo gatherModbusRtuWithTcpServerTunnelInfo) {
    gatherModbusRtuWithTcpServerTunnelInfo.setStationCode(SpringContextHolder.getBean(ElectricFieldService.class).get().getStationCode());
    gatherModbusRtuWithTcpServerTunnelInfo.setDataPoints(null);
		return gatherModbusRtuWithTcpServerTunnelRepository.save(gatherModbusRtuWithTcpServerTunnelInfo);
	}

	/**
	 * 获取到所有的 Modbus Rtu采集通道信息
	 *
	 * @return GatherModbusRtuTunnelInfo all gather modbus rtu tunnel
	 */
	public List<GatherModbusRtuTunnelInfo> getAllGatherModbusRtuTunnel() {
		List<GatherModbusRtuTunnelInfo> gatherModbusRtuTunnelInfoList = gatherModbusRtuTunnelRepository.findAll();
		gatherModbusRtuTunnelInfoList.sort(Comparator.comparing(GatherModbusRtuTunnelInfo::getTunnelName));
		return gatherModbusRtuTunnelInfoList;
	}

	/**
	 * 保存或者修改 Modbus Rtu采集通道信息
	 *
	 * @param gatherModbusRtuTunnelInfo all gather modbus tcp tunnel
	 * @return GatherModbusRtuTunnelInfo all gather modbus rtu tunnel
	 */
	public GatherModbusRtuTunnelInfo saveOrUpdateGatherModbusRtuTunnel(GatherModbusRtuTunnelInfo gatherModbusRtuTunnelInfo) {
		gatherModbusRtuTunnelInfo.setStationCode(SpringContextHolder.getBean(ElectricFieldService.class).get().getStationCode());
		gatherModbusRtuTunnelInfo.setDataPoints(null);
		return gatherModbusRtuTunnelRepository.save(gatherModbusRtuTunnelInfo);
	}


	/**
	 * 保存或者修改 Cdt Rtu采集通道信息
	 *
	 * @param gatherCdtRtuTunnelInfo all gather modbus tcp tunnel
	 * @return GatherCdtRtuTunnelInfo all gather modbus rtu tunnel
	 */
	public GatherCdtRtuTunnelInfo saveOrUpdateGatherCdtRtuTunnel(GatherCdtRtuTunnelInfo gatherCdtRtuTunnelInfo) {
		gatherCdtRtuTunnelInfo.setStationCode(SpringContextHolder.getBean(ElectricFieldService.class).get().getStationCode());
		gatherCdtRtuTunnelInfo.setDataPoints(null);
		return gatherCdtRtuTunnelRepository.save(gatherCdtRtuTunnelInfo);
	}


	/**
	 * 获取到所有的 Modbus Rtu转发通道信息
	 *
	 * @return SenderModbusRtuTunnelInfo
	 */
	public List<SenderModbusRtuTunnelInfo> getAllSenderModbusRtuTunnel() {
		List<SenderModbusRtuTunnelInfo> senderModbusRtuTunnelInfoList = senderModbusRtuTunnelRepository.findAll();
		senderModbusRtuTunnelInfoList.sort(Comparator.comparing(SenderModbusRtuTunnelInfo::getTunnelName));
		return senderModbusRtuTunnelInfoList;
	}


	/**
	 * 获取到所有的 Modbus Tcp转发通道信息
	 *
	 * @return SenderModbusTcpTunnelInfo  modbus 发送通道信息
	 */
	public List<SenderModbusTcpTunnelInfo> getAllSenderModbusTcpTunnel() {
		List<SenderModbusTcpTunnelInfo> senderModbusTcpTunnelInfoList = senderModbusTcpTunnelRepository.findAll();
		senderModbusTcpTunnelInfoList.sort(Comparator.comparing(SenderModbusTcpTunnelInfo::getTunnelName));
		return senderModbusTcpTunnelInfoList;
	}


	/**
	 * 获取到所有的 Cdt  Rtu转发通道信息
	 *
	 * @return SenderCdtRtuTunnelInfo 发送cdt通道信息
	 */
	public List<SenderCdtRtuTunnelInfo> getAllSenderCdtRtuTunnel() {
		List<SenderCdtRtuTunnelInfo> senderCdtRtuTunnelInfoList = senderCdtRtuTunnelRepository.findAll();
		senderCdtRtuTunnelInfoList.sort(Comparator.comparing(SenderCdtRtuTunnelInfo::getTunnelName));
		return senderCdtRtuTunnelInfoList;
	}


	/**
	 * 获取到所有的 Cdt  Rtu采集通道信息
	 *
	 * @return GatherCdtRtuTunnelInfo 接收cdt通道信息
	 */
	public List<GatherCdtRtuTunnelInfo> getAllGatherCdtRtuTunnel() {
		List<GatherCdtRtuTunnelInfo> gatherCdtRtuTunnelInfoList = gatherCdtRtuTunnelRepository.findAll();
		gatherCdtRtuTunnelInfoList.sort(Comparator.comparing(GatherCdtRtuTunnelInfo::getTunnelName));
		return gatherCdtRtuTunnelInfoList;
	}

	/**
	 * 保存或者修改 104tcp采集通道信息
	 *
	 * @param sender104TcpTunnelInfo all gather modbus tcp tunnel
	 * @return Sender104TcpTunnelInfo all gather modbus rtu tunnel
	 */
	public Sender104TcpTunnelInfo saveOrUpdateSender104TcpTunnel(Sender104TcpTunnelInfo sender104TcpTunnelInfo) {
		sender104TcpTunnelInfo.setStationCode(SpringContextHolder.getBean(ElectricFieldService.class).get().getStationCode());
		sender104TcpTunnelInfo.setDataPoints(null);
		return sender104TcpTunnelRepository.save(sender104TcpTunnelInfo);
	}

	/**
	 * 保存或者修改 104tcp采集通道信息
	 *
	 * @param senderModbusRtuTunnelInfo all gather modbus tcp tunnel
	 * @return SenderModbusRtuTunnelInfo all gather modbus rtu tunnel
	 */
	public SenderModbusRtuTunnelInfo saveOrUpdateSenderModbusRtuTunnel(SenderModbusRtuTunnelInfo senderModbusRtuTunnelInfo) {
		senderModbusRtuTunnelInfo.setStationCode(SpringContextHolder.getBean(ElectricFieldService.class).get().getStationCode());
		senderModbusRtuTunnelInfo.setDataPoints(null);
		return senderModbusRtuTunnelRepository.save(senderModbusRtuTunnelInfo);
	}

	/**
	 * 保存或者修改 104tcp采集通道信息
	 *
	 * @param senderModbusTcpTunnelInfo all gather modbus tcp tunnel
	 * @return SenderModbusTcpTunnelInfo all gather modbus rtu tunnel
	 */
	public SenderModbusTcpTunnelInfo saveOrUpdateSenderModbusTcpTunnel(SenderModbusTcpTunnelInfo senderModbusTcpTunnelInfo) {
		senderModbusTcpTunnelInfo.setStationCode(SpringContextHolder.getBean(ElectricFieldService.class).get().getStationCode());
		senderModbusTcpTunnelInfo.setDataPoints(null);
		return senderModbusTcpTunnelRepository.save(senderModbusTcpTunnelInfo);
	}

	/**
	 * 保存或者修改 Cdt Rtu采集通道信息
	 *
	 * @param senderCdtRtuTunnelInfo all gather modbus tcp tunnel
	 * @return SenderCdtRtuTunnelInfo all gather modbus rtu tunnel
	 */
	public SenderCdtRtuTunnelInfo saveOrUpdateSenderCdtRtuTunnel(SenderCdtRtuTunnelInfo senderCdtRtuTunnelInfo) {
		senderCdtRtuTunnelInfo.setDataPoints(null);
		return senderCdtRtuTunnelRepository.save(senderCdtRtuTunnelInfo);
	}

	/**
	 * 获取到符合要求的 通道信息
	 *
	 * @param tunnelInfo tunnel info
	 * @return BaseTunnelInfo tunnel info
	 */
	public List<BaseTunnelInfo> getTunnelInfo(BaseTunnelInfo tunnelInfo) {
		List<BaseTunnelInfo> baseTunnelInfos = new ArrayList<>();
		if (tunnelInfo instanceof Gather104TcpTunnelInfo) {
			baseTunnelInfos.addAll(gather104TcpTunnelRepository.findAll(Example.of((Gather104TcpTunnelInfo) tunnelInfo)));
		} else if (tunnelInfo instanceof Sender104TcpTunnelInfo) {
			baseTunnelInfos.addAll(sender104TcpTunnelRepository.findAll(Example.of((Sender104TcpTunnelInfo) tunnelInfo)));
		} else if (tunnelInfo instanceof GatherModbusRtuTunnelInfo) {
			baseTunnelInfos.addAll(gatherModbusRtuTunnelRepository.findAll(Example.of((GatherModbusRtuTunnelInfo) tunnelInfo)));
		} else if (tunnelInfo instanceof GatherModbusTcpTunnelInfo) {
			baseTunnelInfos.addAll(gatherModbusTcpTunnelRepository.findAll(Example.of((GatherModbusTcpTunnelInfo) tunnelInfo)));
		} else if (tunnelInfo instanceof SenderModbusTcpTunnelInfo) {
			baseTunnelInfos.addAll(senderModbusTcpTunnelRepository.findAll(Example.of((SenderModbusTcpTunnelInfo) tunnelInfo)));
		} else if (tunnelInfo instanceof SenderModbusRtuTunnelInfo) {
			baseTunnelInfos.addAll(senderModbusRtuTunnelRepository.findAll(Example.of((SenderModbusRtuTunnelInfo) tunnelInfo)));
		} else if (tunnelInfo instanceof SenderCdtRtuTunnelInfo) {
			baseTunnelInfos.addAll(senderCdtRtuTunnelRepository.findAll(Example.of((SenderCdtRtuTunnelInfo) tunnelInfo)));
		} else if (tunnelInfo instanceof GatherCdtRtuTunnelInfo) {
			baseTunnelInfos.addAll(gatherCdtRtuTunnelRepository.findAll(Example.of((GatherCdtRtuTunnelInfo) tunnelInfo)));
		} else if (tunnelInfo instanceof FileParseTunnelInfo) {
			baseTunnelInfos.addAll(fileParseTunnelRepository.findAll(Example.of((FileParseTunnelInfo) tunnelInfo)));
		}
		baseTunnelInfos.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
		return baseTunnelInfos;
	}


	public BaseTunnelInfo getTunnelById(String tunnelId, TunnelType type) {
		switch (type) {
			case IEC104TCPMASTER:
				return gather104TcpTunnelRepository.getOne(tunnelId);
			case MODBUSRTUMASTER:
				return gatherModbusRtuTunnelRepository.getOne(tunnelId);
			case MODBUSTCPMASTER:
				return gatherModbusTcpTunnelRepository.getOne(tunnelId);
			case MODBUSTCPSLAVE:
				return senderModbusTcpTunnelRepository.getOne(tunnelId);
			case MODBUSRTUSLAVE:
				return senderModbusRtuTunnelRepository.getOne(tunnelId);
			case CDTRTUSLAVE:
				return senderCdtRtuTunnelRepository.getOne(tunnelId);
			case CDTRTUMASTER:
				return gatherCdtRtuTunnelRepository.getOne(tunnelId);
			case IEC104TCPSLAVE:
				return sender104TcpTunnelRepository.getOne(tunnelId);
			case FILEPARSE:
				return fileParseTunnelRepository.getOne(tunnelId);
      case TCPSERVERASMODBUSMASTER:
        return gatherModbusRtuWithTcpServerTunnelRepository.getOne(tunnelId);
      case TCPCLIENTASMODBUSMASTER:
        return gatherModbusRtuWithTcpClientTunnelRepository.getOne(tunnelId);
		}
		return null;
	}


	/**
	 * 根据转发和采集来查询通道
	 */
	public List<BaseTunnelInfo> findByTunnelType(String tunnelType) {
		List<BaseTunnelInfo> baseTunnelInfos = new ArrayList<>();
		// TunnelType type = null;
		if (("Slave").equals(tunnelType)) {
			baseTunnelInfos.addAll(sender104TcpTunnelRepository.findAll());
			baseTunnelInfos.addAll(senderModbusTcpTunnelRepository.findAll());
			baseTunnelInfos.addAll(senderModbusRtuTunnelRepository.findAll());
			baseTunnelInfos.addAll(senderCdtRtuTunnelRepository.findAll());
		} else if (("Master").equals(tunnelType)) {
			baseTunnelInfos.addAll(gather104TcpTunnelRepository.findAll());
			baseTunnelInfos.addAll(gatherModbusTcpTunnelRepository.findAll());
			baseTunnelInfos.addAll(gatherModbusRtuTunnelRepository.findAll());
			baseTunnelInfos.addAll(gatherCdtRtuTunnelRepository.findAll());
			baseTunnelInfos.addAll(fileParseTunnelRepository.findAll());
      baseTunnelInfos.addAll(gatherModbusRtuWithTcpServerTunnelRepository.findAll());
      baseTunnelInfos.addAll(gatherModbusRtuWithTcpClientTunnelRepository.findAll());
		} else {
			TunnelType type = TunnelType.valueOf(tunnelType);
			switch (type) {
				case IEC104TCPMASTER:
					baseTunnelInfos.addAll(gather104TcpTunnelRepository.findAll());
					break;
				case MODBUSRTUMASTER:
					baseTunnelInfos.addAll(gatherModbusRtuTunnelRepository.findAll());
					break;
				case MODBUSTCPMASTER:
					baseTunnelInfos.addAll(gatherModbusTcpTunnelRepository.findAll());
					break;
				case MODBUSTCPSLAVE:
					baseTunnelInfos.addAll(senderModbusTcpTunnelRepository.findAll());
					break;
				case MODBUSRTUSLAVE:
					baseTunnelInfos.addAll(senderModbusRtuTunnelRepository.findAll());
					break;
				case CDTRTUSLAVE:
					baseTunnelInfos.addAll(senderCdtRtuTunnelRepository.findAll());
					break;
				case CDTRTUMASTER:
					baseTunnelInfos.addAll(gatherCdtRtuTunnelRepository.findAll());
					break;
				case IEC104TCPSLAVE:
					baseTunnelInfos.addAll(sender104TcpTunnelRepository.findAll());
					break;
				case FILEPARSE:
					baseTunnelInfos.addAll(fileParseTunnelRepository.findAll());
					break;
        case TCPSERVERASMODBUSMASTER:
          baseTunnelInfos.addAll(gatherModbusRtuWithTcpServerTunnelRepository.findAll());
          break;
        case TCPCLIENTASMODBUSMASTER:
          baseTunnelInfos.addAll(gatherModbusRtuWithTcpClientTunnelRepository.findAll());
          break;
			}
		}
		baseTunnelInfos.sort(Comparator.comparing(BaseTunnelInfo::getTunnelName));
		return baseTunnelInfos;
	}


	/**
	 * 删除
	 * 删除通道
	 *
	 * @param id         通道编号
	 * @param tunnelType 通道类型
	 * @throws BusinessException 业务异常
	 */
	@Transactional(propagation = Propagation.SUPPORTS)
	public void delete(String id, String tunnelType) throws BusinessException {
		if (StringUtils.isEmpty(id)) {
			throw new BusinessException("通道id不能为空!");
		} else {
			ElectricField electricField = electricFieldService.get();
			TunnelType type = null;
			type = TunnelType.valueOf(tunnelType);
			switch (type) {
				case IEC104TCPMASTER:
					gather104TcpTunnelRepository.deleteById(id);
					break;
				case MODBUSRTUMASTER:
					gatherModbusRtuTunnelRepository.deleteById(id);
					break;
				case MODBUSTCPMASTER:
					gatherModbusTcpTunnelRepository.deleteById(id);
					break;
				case MODBUSTCPSLAVE:
					senderModbusTcpTunnelRepository.deleteById(id);
					break;
				case MODBUSRTUSLAVE:
					senderModbusRtuTunnelRepository.deleteById(id);
					break;
				case CDTRTUSLAVE:
					senderCdtRtuTunnelRepository.deleteById(id);
					break;
				case CDTRTUMASTER:
					gatherCdtRtuTunnelRepository.deleteById(id);
					break;
				case IEC104TCPSLAVE:
					sender104TcpTunnelRepository.deleteById(id);
					break;
				case FILEPARSE:
					fileParseTunnelRepository.deleteById(id);
					break;
        case TCPSERVERASMODBUSMASTER:
          gatherModbusRtuWithTcpServerTunnelRepository.deleteById(id);
          break;
        case TCPCLIENTASMODBUSMASTER:
          gatherModbusRtuWithTcpClientTunnelRepository.deleteById(id);
          break;
			}
			if (electricField.getElectricFieldTypeEnum().toString().equals("E1")) {
				List<WeatherStationInfo> weatherStationInfoList = weatherStationInfoService.getAll();
				List<WeatherStationInfo> filterWeatherStationInfoList = weatherStationInfoList.stream().filter(w -> w.getBindTunnel() != null && w.getBindTunnel().equals(id)).collect(Collectors.toList());
				if (filterWeatherStationInfoList.size() > 0) {
					for (WeatherStationInfo weatherStationInfo : filterWeatherStationInfoList) {
						weatherStationInfo.setBindTunnel(null);
						weatherStationInfoService.update(weatherStationInfo);
					}
				}
			} else {
				List<WindTowerInfo> windTowerInfoList = windTowerInfoService.getAll();
				List<WindTowerInfo> filterWindTowerInfoList = windTowerInfoList.stream().filter(w -> w.getBindTunnel() != null && w.getBindTunnel().equals(id)).collect(Collectors.toList());
				if (filterWindTowerInfoList.size() > 0 && filterWindTowerInfoList != null) {
					for (WindTowerInfo windTowerInfo : filterWindTowerInfoList) {
						windTowerInfo.setBindTunnel(null);
						windTowerInfoService.update(windTowerInfo);
					}
				}

			}

		}
	}

	/**
	 * 关闭通道byId
	 *
	 * @param tunnelId tunnel id
	 * @return BaseTunnelInfo base tunnel info
	 */
	public BaseTunnelInfo shuntDownTunnelById(String tunnelId) {
		BaseTunnelInfo baseTunnelInfo = null;
		if (gather104TcpTunnelRepository.existsById(tunnelId)) {
			Gather104TcpTunnelInfo info = new Gather104TcpTunnelInfo();
			info.setId(tunnelId);
			info.setIsEnable(false);
			baseTunnelInfo = gather104TcpTunnelRepository.save(info);
		} else if (sender104TcpTunnelRepository.existsById(tunnelId)) {
			Sender104TcpTunnelInfo info = new Sender104TcpTunnelInfo();
			info.setId(tunnelId);
			info.setIsEnable(false);
			baseTunnelInfo = sender104TcpTunnelRepository.save(info);
		} else if (gatherModbusTcpTunnelRepository.existsById(tunnelId)) {
			GatherModbusTcpTunnelInfo info = new GatherModbusTcpTunnelInfo();
			info.setId(tunnelId);
			info.setIsEnable(false);
			baseTunnelInfo = gatherModbusTcpTunnelRepository.save(info);
		} else if (senderModbusTcpTunnelRepository.existsById(tunnelId)) {
			SenderModbusTcpTunnelInfo info = new SenderModbusTcpTunnelInfo();
			info.setId(tunnelId);
			info.setIsEnable(false);
			baseTunnelInfo = senderModbusTcpTunnelRepository.save(info);
		} else if (gatherModbusRtuTunnelRepository.existsById(tunnelId)) {
			GatherModbusRtuTunnelInfo info = new GatherModbusRtuTunnelInfo();
			info.setId(tunnelId);
			info.setIsEnable(false);
			baseTunnelInfo = gatherModbusRtuTunnelRepository.save(info);
		} else if (senderCdtRtuTunnelRepository.existsById(tunnelId)) {
			SenderCdtRtuTunnelInfo info = new SenderCdtRtuTunnelInfo();
			info.setId(tunnelId);
			info.setIsEnable(false);
			baseTunnelInfo = senderCdtRtuTunnelRepository.save(info);
		} else if (senderModbusRtuTunnelRepository.existsById(tunnelId)) {
			SenderModbusRtuTunnelInfo info = new SenderModbusRtuTunnelInfo();
			info.setId(tunnelId);
			info.setIsEnable(false);
			baseTunnelInfo = senderModbusRtuTunnelRepository.save(info);
		} else if (gatherCdtRtuTunnelRepository.existsById(tunnelId)) {
			GatherCdtRtuTunnelInfo info = new GatherCdtRtuTunnelInfo();
			info.setId(tunnelId);
			info.setIsEnable(false);
			baseTunnelInfo = gatherCdtRtuTunnelRepository.save(info);
		}
		return baseTunnelInfo;
	}

	/**
	 * 映射到bean
	 * 将map集合中的数据转化为指定对象的同名属性中
	 *
	 * @param <T>   类型
	 * @param map   属性名 value
	 * @param clazz clazz
	 * @return {@link T}
	 * @throws Exception 异常
	 */
	public static <T> T mapToBean(Map<String, Object> map, Class<T> clazz) throws Exception {
		T bean = clazz.newInstance();
		BeanMap beanMap = BeanMap.create(bean);
		beanMap.putAll(map);
		return bean;
	}

	/*
	 *
	 * 删除通道下的点表,
	 * 删除的是采集点表要删除与其关联的转发点表
	 * */
	public void deleteDataPointById(String id, String tunnelType) {
		TunnelType type = TunnelType.valueOf(tunnelType);
		String str = type.toString();
		if (str.substring(str.length() - 6).equals("MASTER")) {
			List<ProtocolGatherDataPoint> protocolGatherDataPoints = protocolGatherDataPointService.getByTunnelId(id);
			for (ProtocolGatherDataPoint protocolGatherDataPoint : protocolGatherDataPoints) {
				protocolGatherDataPointService.deleteById(protocolGatherDataPoint.getId());
//        protocolGatherDataPointRepository.delete(protocolGatherDataPoint);
			}
		} else {
			List<ProtocolSenderDataPoint> protocolSenderDataPoints = protocolSenderDataPointService.findByTunnelId(id);
			for (ProtocolSenderDataPoint protocolSenderDataPoint : protocolSenderDataPoints) {
				protocolSenderDataPointRepository.delete(protocolSenderDataPoint);
			}
		}

	}



}




