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

#include <algorithm>
#include <cmath>
#include <limits>
#include <memory>
#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>

namespace milotic_tlbmc {
namespace thermal {

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

  auto dff_controller = absl::WrapUnique(new DffController(
      params.id, params.zone_manager, std::move(params.dff_loop),
      std::move(params.input_sensors),
      std::move(params.affected_controller_ids)));

  return dff_controller;
}

void DffController::ProcessThermalLoop() {
  const double input = ProcessInput();

  // If the input is invalid, use the previous output.
  double output = GetLastOutput();
  if (std::isfinite(input)) {
    output =
        GetDffLoop()->ExecuteDffLoop(input, zone_owner_->GetDebugDffEnabled());
  }

  ProcessOutput(output);
}

double DffController::ProcessInput() {
  double input_value = std::numeric_limits<double>::lowest();
  bool is_input_acceptable = false;

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

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

    input_value = std::max(input_value, sensor_value);
    is_input_acceptable = true;
  }

  // If no input is acceptable, return NaN to indicate the invalidness.
  if (!is_input_acceptable) {
    input_value = std::numeric_limits<double>::quiet_NaN();
    zone_owner_->TryLogThermalDebugMessage(absl::StrFormat(
        "DFF controller %s has fetched no valid input sensor reading.\n",
        GetId()));
  } else {
    zone_owner_->TryLogThermalDebugMessage(absl::StrFormat(
        "DFF controller %s chose the input value %lf\n", GetId(), input_value));
  }

  return input_value;
}

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

nlohmann::json DffController::ToJson() const {
  nlohmann::json json;
  json["H1Coefficient"] = dff_loop_->GetCoeffH1();
  json["H2Coefficient"] = dff_loop_->GetCoeffH2();
  json["H3Coefficient"] = dff_loop_->GetCoeffH3();
  json["F1Coefficient"] = dff_loop_->GetCoeffF1();
  json["F2Coefficient"] = dff_loop_->GetCoeffF2();
  json["F3Coefficient"] = dff_loop_->GetCoeffF3();
  json["ReferencePower"] = dff_loop_->GetReferencePower();
  json["OutLimitMax"] = dff_loop_->GetOutputLimitMax();
  json["OutLimitMin"] = dff_loop_->GetOutputLimitMin();
  json["SlewNeg"] = dff_loop_->GetSlewNeg();
  json["SlewPos"] = dff_loop_->GetSlewPos();
  json["AffectedControllerIds"] = nlohmann::json::array();
  for (const std::string& affected_controller_id : affected_controller_ids_) {
    json["AffectedControllerIds"].push_back(affected_controller_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
