#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_THERMAL_CONTROLLER_SECOND_ORDER_ADRC_CONTROLLER_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_THERMAL_CONTROLLER_SECOND_ORDER_ADRC_CONTROLLER_H_

#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/attributes.h"
#include "absl/base/nullability.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include <nlohmann/json_fwd.hpp>
#include "thermal_config.pb.h"
#include "thermal_controller_specification.pb.h"
#include "tlbmc/thermal/controller/algorithm/second_order_adrc.h"
#include "tlbmc/thermal/controller/controller.h"
#include "tlbmc/thermal/zone_manager.h"

namespace milotic_tlbmc {
namespace thermal {

constexpr double kDefaultSecondOrderAdrcSetpointValue = 0.0;

struct SecondOrderAdrcControllerParameters {
  std::string id;
  ZoneManager* absl_nonnull zone_manager ABSL_REQUIRE_EXPLICIT_INIT;
  std::unique_ptr<SecondOrderAdrcThermalLoop> absl_nonnull
  second_order_adrc_loop ABSL_REQUIRE_EXPLICIT_INIT;
  double setpoint = kDefaultSecondOrderAdrcSetpointValue;
  std::vector<std::string> input_sensors;
  std::vector<std::vector<std::string>> disturbance_sensor_lists;
};

/**
 * `SecondOrderAdrcController` provides a connection between the thermal zone
 * manager and the 2nd-order ADRC thermal loop. It will handle the sensor
 * reading & fan output process, and the 2nd-order ADRC thermal loop
 * calculations.
 *
 * The 2nd-order ADRC loop and its controller is 1:1 in bi-jection relationship.
 *
 * This class is not thread-safe.
 */
class SecondOrderAdrcController : public ThermalController {
 public:
  ~SecondOrderAdrcController() final = default;

  static absl::StatusOr<std::unique_ptr<SecondOrderAdrcController>> Create(
      SecondOrderAdrcControllerParameters params);

  void ProcessThermalLoop() final;
  double ProcessInput() final;
  void ProcessOutput(double output) final;

  std::string GetId() const final { return id_; }
  bool IsFanController() const final { return false; }
  bool IsSupportiveController() const final { return false; }
  const std::vector<std::string>& GetAffectedControllerIds() const final {
    return empty_affected_controller_ids_;
  }
  void AdjustSetpoint(double offset) final { setpoint_ += offset; }

  double GetSetpoint() const { return setpoint_; }

  ZoneManager* GetZoneManager() const { return zone_owner_; }

  SecondOrderAdrcThermalLoop* GetSecondOrderAdrcLoop() const {
    return second_order_adrc_loop_.get();
  }

  void AddInputSensor(const std::string& input_sensor) {
    input_sensors_.push_back(input_sensor);
  }
  const std::vector<std::string>& GetInputSensors() const {
    return input_sensors_;
  }

  nlohmann::json ToJson() const;

 protected:
  explicit SecondOrderAdrcController(
      absl::string_view id, ZoneManager* zone_manager,
      std::unique_ptr<SecondOrderAdrcThermalLoop> absl_nonnull
      second_order_adrc_loop,
      double setpoint, std::vector<std::string> input_sensors,
      std::vector<std::vector<std::string>> disturbance_sensor_lists)
      : ThermalController(),
        id_(id),
        zone_owner_(zone_manager),
        second_order_adrc_loop_(std::move(second_order_adrc_loop)),
        setpoint_(setpoint),
        input_sensors_(std::move(input_sensors)),
        disturbance_sensor_lists_(std::move(disturbance_sensor_lists)) {
    input_disturbances_.resize(disturbance_sensor_lists_.size(), 0.0);
  }

  void ProcessInputDisturbances();
  static std::optional<double> ProcessSensorInputs(
      absl::Span<const std::string> sensors, ZoneManager* zone_manager);

 private:
  const std::string id_;
  // Use a simple pointer here to avoid circular dependency.
  // Every `ZoneManager` will be owned by the thermal control collector of
  // tlBMC, and will live as long as the thermal control service is on.
  ZoneManager* zone_owner_ = nullptr;

  // Every `SecondOrderAdrcThermalLoop` will be owned by its thermal controller,
  // and will live as long as the thermal control service is on.
  std::unique_ptr<SecondOrderAdrcThermalLoop> second_order_adrc_loop_;
  double setpoint_ = kDefaultSecondOrderAdrcSetpointValue;
  std::vector<std::string> input_sensors_;
  std::vector<std::vector<std::string>> disturbance_sensor_lists_;
  std::vector<double> input_disturbances_;
  // An empty vector to return by reference for `GetAffectedControllerIds`.
  const std::vector<std::string> empty_affected_controller_ids_;
};

}  // namespace thermal
}  // namespace milotic_tlbmc

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_THERMAL_CONTROLLER_SECOND_ORDER_ADRC_CONTROLLER_H_
