package com.jiayue.ipfcst.dataexchange.container;

import com.jiayue.ipfcst.common.core.util.SpringContextHolder;
import com.jiayue.ipfcst.common.data.entity.*;
import com.jiayue.ipfcst.console.service.SysParameterService;
import com.jiayue.ipfcst.dataexchange.dataprocesser.datapacker.AbstractDataPacker;
import com.jiayue.ipfcst.dataexchange.dataprocesser.datapacker.iml.EquipmentDataPacker;
import com.jiayue.ipfcst.dataexchange.dataprocesser.datapacker.iml.PowerStationDataPacker;
import com.jiayue.ipfcst.dataexchange.dataprocesser.datapacker.iml.PowerStationDataPackerOne;
import com.jiayue.ipfcst.dataexchange.service.SaveEquipmentStatusData;
import com.jiayue.ipfcst.dataexchange.service.equipmentstatusdata.*;

import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 实体类装载器的容器
 *
 * @author 修唯xiuwei
 * @version 3.0
 */
public class DataPackerContainer {


  /**
   * 各种设备状态对应的service
   */
  RecurringTaskContainer recurringTaskContainer = RecurringTaskContainer.getInstance();
  InverterStatusDataService inverterStatusDataService = SpringContextHolder.getBean(InverterStatusDataService.class);
  PowerStationStatusDataService powerStationStatusDataService = SpringContextHolder.getBean(PowerStationStatusDataService.class);
  PowerStationStatusDataOneService powerStationStatusDataOneService = SpringContextHolder.getBean(PowerStationStatusDataOneService.class);
  WeatherStationStatusDataService weatherStationStatusDataService = SpringContextHolder.getBean(WeatherStationStatusDataService.class);
  WindTowerStatusDataService windTowerStatusDataService = SpringContextHolder.getBean(WindTowerStatusDataService.class);
  WindTurbineStatusDataService windTurbineStatusDataService = SpringContextHolder.getBean(WindTurbineStatusDataService.class);
  AGC_AVCStatusDataService agc_avcStatusDataService = SpringContextHolder.getBean(AGC_AVCStatusDataService.class);
  SysParameterService sysParameterService = SpringContextHolder.getBean(SysParameterService.class);
  SaveEquipmentStatusData saveEquipmentStatusData = SpringContextHolder.getBean(SaveEquipmentStatusData.class);

  /**
   * packer 的池子
   */
  private Map<String, AbstractDataPacker> packers = new ConcurrentHashMap<>();

  private Map<String, Callable> tasks = new ConcurrentHashMap<>();

  private DataPackerContainer() {
  }

  /**
   * 返回容器对象
   *
   * @return the instance
   */
  public static final DataPackerContainer getInstance() {
    return LazyHolder.INSTANCE;
  }

  /**
   * 添加packer  并启动定时任务
   *
   * @param equipmentNo 设备NO
   * @param packer      组装器
   * @return {@link  AbstractDataPacker}
   */
  public synchronized Map<String, AbstractDataPacker> addPacker(String equipmentNo, AbstractDataPacker packer) {
    if (this.packers.containsKey(equipmentNo)) {
      removePacker(equipmentNo);
    }
    this.packers.put(equipmentNo, packer);
    if ("1".equals(sysParameterService.getSysParameter("EquipmentDataSaveMethod", "1"))) {
      //使用spring定时任务 存数据
      saveEquipmentStatusData.addPacker(packer);
    } else {
      tasks.put(equipmentNo, startPackageTask(packer));
    }
    return this.packers;
  }

  /**
   * 删除组装器
   * 移除packer
   *
   * @param equipmentNo 设备号
   * @return {@link AbstractDataPacker}
   */
  public synchronized Map<String, AbstractDataPacker> removePacker(String equipmentNo) {
    AbstractDataPacker packer = this.packers.remove(equipmentNo);
    if ("1".equals(sysParameterService.getSysParameter("EquipmentDataSaveMethod", "1"))) {
      //使用spring定时任务 存数据
      if (packer != null) {
        saveEquipmentStatusData.removePacker(packer);
      }
    } else {
      recurringTaskContainer.removeTask(this.tasks.get(equipmentNo));
      this.tasks.remove(equipmentNo);
    }
    return this.packers;
  }

  /**
   * 获取packer
   *
   * @param equipmentNo 设备No
   * @return {@link AbstractDataPacker}
   */
  public synchronized AbstractDataPacker getPacker(String equipmentNo) {
    return this.packers.get(equipmentNo);
  }

  /**
   * 根据新增的设备 增加定时入库的定时任务
   *
   * @param equipmentDataPacker 设备数据组装器
   * @return {@link Callable}
   */
  public Callable startPackageTask(AbstractDataPacker equipmentDataPacker) {
    Class clazz = equipmentDataPacker.getT().getClass();
    switch (clazz.getSimpleName()) {
      case "InverterStatusData":
        return recurringTaskContainer.addRecurringTask(equipmentDataPacker.getInterval(), "存入逆变器状态信息任务", () -> inverterStatusDataService.save(((EquipmentDataPacker<InverterStatusData>) equipmentDataPacker).packageData()));
      case "PowerStationStatusData":
        return recurringTaskContainer.addRecurringTask(equipmentDataPacker.getInterval(), "存入光伏场站状态信息任务", () -> powerStationStatusDataService.save(((PowerStationDataPacker) equipmentDataPacker).packageData()));
      case "PowerStationStatusDataOne":
        return recurringTaskContainer.addRecurringTask(equipmentDataPacker.getInterval(), "存入风电场站状态信息任务", () -> powerStationStatusDataOneService.save(((PowerStationDataPackerOne) equipmentDataPacker).packageData()));
      case "WeatherStationStatusData":
        return recurringTaskContainer.addRecurringTask(equipmentDataPacker.getInterval(), "存入气象站状态信息任务", () -> weatherStationStatusDataService.save(((EquipmentDataPacker<WeatherStationStatusData>) equipmentDataPacker).packageData()));
      case "WindTowerStatusData":
        return recurringTaskContainer.addRecurringTask(equipmentDataPacker.getInterval(), "存入测风塔状态信息任务", () -> windTowerStatusDataService.save(((EquipmentDataPacker<WindTowerStatusData>) equipmentDataPacker).packageData()));
      case "WindTurbineStatusData":
        return recurringTaskContainer.addRecurringTask(equipmentDataPacker.getInterval(), "存入风机状态信息任务", () -> windTurbineStatusDataService.save(((EquipmentDataPacker<WindTurbineStatusData>) equipmentDataPacker).packageData()));
      case "AGC_AVCStatusData":
        return recurringTaskContainer.addRecurringTask(equipmentDataPacker.getInterval(), "存入AGC_AVC状态信息任务", () -> agc_avcStatusDataService.save(((EquipmentDataPacker<AGC_AVCStatusData>) equipmentDataPacker).packageData()));
      default:
        return null;
    }
  }

  private static class LazyHolder {
    private static final DataPackerContainer INSTANCE = new DataPackerContainer();
  }

}
