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

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

#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 <nlohmann/json_fwd.hpp>
#include "tlbmc/thermal/zone_manager.h"

namespace milotic_tlbmc {
namespace thermal {

absl::StatusOr<std::unique_ptr<EatController>> EatController::Create(
    EatControllerParameters params) {
  if (params.input_sensors.empty()) {
    return absl::InvalidArgumentError(absl::StrFormat(
        "No input sensor is assigned to EAT controller `%s`!", params.id));
  }
  if (params.affected_zone_ids.empty()) {
    return absl::InvalidArgumentError(absl::StrFormat(
        "No affected zone is assigned to EAT controller `%s`!", params.id));
  }

  return absl::WrapUnique(new EatController(
      params.id, params.zone_manager, std::move(params.eat_loop),
      std::move(params.input_sensors), std::move(params.affected_zones),
      std::move(params.affected_zone_ids)));
}

void EatController::ProcessThermalLoop() {
  double average_sensor_value = ProcessInput();

  std::optional<double> eat_value =
      eat_loop_->ExecuteEatLoop(average_sensor_value);

  if (eat_value) {
    ProcessOutput(eat_value.value());
  }
}

double EatController::ProcessInput() {
  int valid_sensor_input_count = 0;
  double sum_sensor_value = 0.0;
  for (const std::string& sensor_id : input_sensors_) {
    double sensor_value =
        zone_owner_->GetSensorReadings(sensor_id).scaled_value;

    if (std::isnan(sensor_value) || !std::isfinite(sensor_value)) {
      continue;
    }

    valid_sensor_input_count++;
    sum_sensor_value += sensor_value;
  }

  return (valid_sensor_input_count > 0
              ? sum_sensor_value / static_cast<double>(valid_sensor_input_count)
              : std::numeric_limits<double>::quiet_NaN());
}

void EatController::ProcessOutput(double output) {
  for (ZoneManager* affected_zone : affected_zones_) {
    affected_zone->AdjustSetpoint(output);
    zone_owner_->TryLogThermalDebugMessage(absl::StrFormat(
        "Zone %d offsets setpoint by %f, requested by EAT controller `%s`",
        affected_zone->GetId(), output, id_));
  }
  if (zone_owner_->GetDebugEnabled()) {
    zone_owner_->AppendSampledData(absl::StrCat(output, ","));
  }
}

nlohmann::json EatController::ToJson() const {
  nlohmann::json json;
  json["NegativeSlewRate"] = eat_loop_->GetSlewNeg();
  json["PositiveSlewRate"] = eat_loop_->GetSlewPos();
  json["OutLimitMax"] = eat_loop_->GetOutputLimitMax();
  json["OutLimitMin"] = eat_loop_->GetOutputLimitMin();
  json["AffectedZoneIds"] = nlohmann::json::array();
  for (int affected_zone_id : affected_zone_ids_) {
    json["AffectedZoneIds"].push_back(affected_zone_id);
  }
  json["Inputs"] = nlohmann::json::array();
  for (const std::string& input : input_sensors_) {
    json["Inputs"].push_back(input);
  }
  return json;
}

}  // namespace thermal
}  // namespace milotic_tlbmc
