#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_THERMAL_CONTROLLER_STEPWISE_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_THERMAL_CONTROLLER_STEPWISE_H_

#include <limits>
#include <vector>

#include "thermal_config.pb.h"

namespace milotic_tlbmc {
namespace thermal {

/*
 * `StepwiseThermalLoop` is a thermal control algorithm that outputs a value
 * different from the last output only when the delta between the current and
 * the last input that triggered an output search is large enough.
 *
 * If the delta is large enough, the triggered output search will return the
 * corresponding `output` of the largest manually configured `threshold` that is
 * smaller than or equal to `input`.
 *
 * This class is not thread-safe.
 *
 * This class is created and revised based on the stepwise structs at
 * https://github.com/openbmc/phosphor-pid-control/blob/master/pid/ec/stepwise.hpp
 * and the stepwise controller at
 * https://github.com/openbmc/phosphor-pid-control/blob/master/pid/stepwisecontroller.hpp
 */
class StepwiseThermalLoop {
 public:
  StepwiseThermalLoop() = default;

  explicit StepwiseThermalLoop(const StepwiseLoopConfig& stepwise_params)
      : stepwise_params_(stepwise_params) {
    if (stepwise_params.sample_time_sec() <= 0) {
      stepwise_params_.set_sample_time_sec(1.0);
    }
  }

  /*
   * `ExecuteStepwiseLoop` performs exactly one iteration of a stepwise loop.
   *
   * If this is the first iteration, or the delta between the current and the
   * last input is larger than the corresponding hysteresis value, it will
   * proceed to the next step, otherwise, the last output will be returned.
   *
   * As the next step, it will output the corresponding `stepwise_output`
   * of the largest manually configured `threshold` that is smaller than or
   * equal to `input`.
   *
   * If no such critical point exists (i.e., `input` is smaller than the
   * smallest `threshold`), it will output the `stepwise_output` of the first
   * critical point by default.
   */
  double ExecuteStepwiseLoop(double input);

  void SetCriticalPoints(
      const std::vector<StepwiseCriticalPoint>& critical_points) {
    stepwise_params_.clear_critical_points();
    for (const StepwiseCriticalPoint& critical_point : critical_points) {
      *stepwise_params_.add_critical_points() = critical_point;
    }
  }

  StepwiseCriticalPoint GetCriticalPointAt(int index) const {
    return stepwise_params_.critical_points(index);
  }
  int GetCriticalPointsSize() const {
    return stepwise_params_.critical_points_size();
  }

  void SetPositiveHysteresis(double positive_hysteresis) {
    stepwise_params_.set_positive_hysteresis(positive_hysteresis);
  }
  double GetPositiveHysteresis() const {
    return stepwise_params_.positive_hysteresis();
  }

  void SetNegativeHysteresis(double negative_hysteresis) {
    stepwise_params_.set_negative_hysteresis(negative_hysteresis);
  }
  double GetNegativeHysteresis() const {
    return stepwise_params_.negative_hysteresis();
  }

  void SetLastInput(double last_input) { last_input_ = last_input; }
  double GetLastInput() const { return last_input_; }

  void SetLastOutput(double last_output) { last_output_ = last_output; }
  double GetLastOutput() const { return last_output_; }

  double GetSampleTime() const { return stepwise_params_.sample_time_sec(); }

 protected:
  double FindStepwiseOutput(double input) const;

 private:
  double last_input_ = std::numeric_limits<double>::quiet_NaN();
  double last_output_ = std::numeric_limits<double>::quiet_NaN();

  StepwiseLoopConfig
      stepwise_params_;  // The parameters for this stepwise thermal loop.
};

}  // namespace thermal
}  // namespace milotic_tlbmc

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_THERMAL_CONTROLLER_STEPWISE_H_
