package com.jiayue.ipfcst.dataexchange.dataprocesser.datapacker.iml;


import java.math.BigDecimal;
import java.util.Map;

/**
 * 样板机法理论功率计算器
 * 在功率预测v3 中作为基类  以后可能会有其他用途 单拿出来了
 *
 * @author: xiuwei
 * @version:
 */
public class AbstractBenchmarkingPowerCalculator {

  /**
   * 所有机器的类型 机器功率的情况
   */
  Map<String, AbstractOneModelPower> modelPowerMap;

  /**
   * 获取到所有的机器的总可用功率
   *
   * @return BigDecimal 可用功率
   */
  public BigDecimal getTotalAvailablePower() {
    BigDecimal total = BigDecimal.valueOf(0);
    for (AbstractOneModelPower p : modelPowerMap.values()) {
      total = total.add(p.updateData().oneModelTotalAvailablePower());
    }
    return total;
  }


  /**
   * 获取到所有的机器的总理论功率
   *
   * @return BigDecimal 理论功率
   */
  public BigDecimal getTotalTheoreticalPower() {
    BigDecimal total = BigDecimal.valueOf(0);
    for (AbstractOneModelPower p : modelPowerMap.values()) {
      total = total.add(p.updateData().oneModelTotalTheoreticalPower());
    }
    return total;
  }


  /**
   * 其中一种类型的机器的功率
   */
  abstract class AbstractOneModelPower {

    /**
     * 设备id 样板机功率  引入设备id 的目的是发现停止运行的样板机 进而在计算时剔除
     */
    Map<Integer, BigDecimal> benchmarkPower;

    /**
     * 设备id  所有该类型机的状态 true：运行   false：停机
     */
    Map<Integer, Boolean> machineStatus;

    /**
     * 计算该种类型的机器的可用功率
     * 平均值 * 正在运行的个数
     *
     * @return BigDecimal 某类型总可用功率
     */
    protected BigDecimal oneModelTotalAvailablePower() {
      int num = 0;
      for (boolean b : machineStatus.values()) {
        if (b) {
          num++;
        }
      }
      return getBenchmarkAvg().multiply(BigDecimal.valueOf(num));
    }


    /**
     * 计算该种类型的机器的理论功率
     * 平均值 * 该类风机的总个数
     *
     * @return BigDecimal 某类型总理论功率
     */
    protected BigDecimal oneModelTotalTheoreticalPower() {
      return getBenchmarkAvg().multiply(BigDecimal.valueOf(machineStatus.size()));
    }


    /**
     * 得到样板机的功率平均数（刨除未运行的样板机）
     *
     * @return {@link BigDecimal}
     */
    protected BigDecimal getBenchmarkAvg() {
      BigDecimal avg = BigDecimal.valueOf(0.0);
      int totalSample = 0;
      for (Map.Entry<Integer, BigDecimal> e : benchmarkPower.entrySet()) {
        if (machineStatus.containsKey(e.getKey()) && machineStatus.get(e.getKey())) {
          avg = avg.add(e.getValue());
          totalSample++;
        }
      }
      if (totalSample != 0) {
        avg = avg.divide(BigDecimal.valueOf(totalSample));
      }
      return avg;
    }

    /**
     * 刷新数据
     *
     * @return AbstractOneModelPower 返回对象 连点
     */
    public abstract AbstractOneModelPower updateData();

  }


}

