#include "tlbmc/thermal/controller/first_order_adrc_controller.h"

#include <algorithm>
#include <cmath>
#include <limits>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/types/span.h"
#include <nlohmann/json.hpp>
#include "tlbmc/thermal/zone_manager.h"

namespace milotic_tlbmc {
namespace thermal {

absl::StatusOr<std::unique_ptr<FirstOrderAdrcController>>
FirstOrderAdrcController::Create(FirstOrderAdrcControllerParameters params) {
  if (params.input_sensors.empty()) {
    return absl::InvalidArgumentError(absl::StrFormat(
        "No input sensor is assigned to FirstOrderAdrc controller `%s`!",
        params.id));
  }

  auto first_order_adrc_controller =
      absl::WrapUnique(new FirstOrderAdrcController(
          params.id, params.zone_manager,
          std::move(params.first_order_adrc_loop), params.setpoint,
          std::move(params.input_sensors)));

  return first_order_adrc_controller;
}

void FirstOrderAdrcController::ProcessThermalLoop() {
  double input = ProcessInput();
  double setpoint = GetSetpoint();

  ProcessOutput(GetFirstOrderAdrcLoop()->ExecuteFirstOrderAdrcLoop(
      setpoint, input, zone_owner_->GetDebugEnabled()));
}

double FirstOrderAdrcController::ProcessInput() {
  std::optional<double> input_value =
      ProcessSensorInputs(input_sensors_, zone_owner_);

  // If no input is acceptable, return `setpoint_` to indicate the invalidness.
  // This will make the ADRC error to be zero.
  if (!input_value.has_value()) {
    input_value = GetSetpoint();
    zone_owner_->TryLogThermalDebugMessage(absl::StrFormat(
        "FirstOrderAdrc controller %s chose the setpoint %lf as the input "
        "value, as there is no valid input sensor reading\n",
        GetId(), GetSetpoint()));
  } else {
    zone_owner_->TryLogThermalDebugMessage(absl::StrFormat(
        "FirstOrderAdrc controller %s chose the input value %lf\n", GetId(),
        *input_value));
  }

  return *input_value;
}

void FirstOrderAdrcController::ProcessOutput(double output) {
  zone_owner_->AddSetpoint(GetId(), output);
  zone_owner_->TryLogThermalDebugMessage(absl::StrFormat(
      "FirstOrderAdrc controller %s outputs setpoint: %lf\n", GetId(), output));
  if (zone_owner_->GetDebugEnabled()) {
    zone_owner_->AppendSampledData(absl::StrCat(output, ","));
  }
}

std::optional<double> FirstOrderAdrcController::ProcessSensorInputs(
    absl::Span<const std::string> sensors, ZoneManager* zone_manager) {
  std::optional<double> input_value = std::nullopt;

  for (const std::string& sensor : sensors) {
    double sensor_value = zone_manager->GetSensorReadings(sensor).scaled_value;

    // Sensor readings must not be NaN.
    if (!std::isfinite(sensor_value)) {
      continue;
    }

    input_value = input_value.has_value() ? std::max(*input_value, sensor_value)
                                          : sensor_value;
  }

  return input_value;
}

nlohmann::json FirstOrderAdrcController::ToJson() const {
  nlohmann::json json;
  json["SampleTimeSec"] = first_order_adrc_loop_->GetSampleTimeSec();
  json["SettleTimeSec"] = first_order_adrc_loop_->GetSettleTimeSec();
  json["B0"] = first_order_adrc_loop_->GetB0();
  json["ObserverBandwidthFactor"] =
      first_order_adrc_loop_->GetObserverBandwidthFactor();
  json["OutLimitMax"] = first_order_adrc_loop_->GetOutputLimitMax();
  json["OutLimitMin"] = first_order_adrc_loop_->GetOutputLimitMin();
  json["SetPoint"] = GetSetpoint();
  json["Inputs"] = nlohmann::json::array();
  for (const std::string& input : input_sensors_) {
    json["Inputs"].push_back(input);
  }
  return json;
}

}  // namespace thermal
}  // namespace milotic_tlbmc
