#include "tlbmc/thermal/controller/algorithm/dff.h"

#include <algorithm>
#include <limits>

#include "absl/log/log.h"
#include "absl/strings/str_format.h"

namespace milotic_tlbmc {
namespace thermal {

double DffThermalLoop::ApplyLowPassFilterToDisturbance(
    double disturbance, bool enable_calculation_log) const {
  double filtered_disturbance = GetCoeffH1() * disturbance +
                                GetCoeffH2() * GetLastDisturbance() +
                                GetCoeffH3() * GetLastFilteredDisturbance();

  if (enable_calculation_log) {
    LOG(WARNING)
        << "[Thermal Debug]: "
        << absl::StrFormat(
               "After applying low-pass filter, filtered disturbance: %lf, "
               "with input disturbance: %lf, previous disturbance: %lf, and "
               "previous filtered disturbance: %lf",
               filtered_disturbance, disturbance, GetLastDisturbance(),
               GetLastFilteredDisturbance());
  }

  return filtered_disturbance;
}

double DffThermalLoop::ExecuteDffLoop(double disturbance,
                                      bool enable_calculation_log) {
  // Apply low pass filter on the disturbance measurement to attenuate
  // high-frequency components that the feedforward controller cannot
  // effectively handle.
  double filtered_disturbance =
      ApplyLowPassFilterToDisturbance(disturbance, enable_calculation_log);

  double dff_value =
      GetCoeffF1() * (filtered_disturbance - GetReferencePower()) +
      GetCoeffF2() * (GetLastFilteredDisturbance() - GetReferencePower()) +
      GetCoeffF3() * GetLastDffValue();

  SetLastDisturbance(disturbance);
  SetLastFilteredDisturbance(filtered_disturbance);
  SetLastDffValue(dff_value);

  double output = dff_value;

  if (enable_calculation_log) {
    LOG(WARNING) << "[Thermal Debug]: "
                 << absl::StrFormat(
                        "F1: %lf; F2: %lf; F3: %lf; H1: %lf; H2: %lf; H3: "
                        "%lf; output: %lf; disturbance: %lf; last "
                        "disturbance: %lf; last filtered disturbance: %lf; "
                        "last DFF value: %lf",
                        GetCoeffF1(), GetCoeffF2(), GetCoeffF3(), GetCoeffH1(),
                        GetCoeffH2(), GetCoeffH3(), output, disturbance,
                        GetLastDisturbance(), GetLastFilteredDisturbance(),
                        GetLastDffValue());
  }

  // Apply slew rate clamping
  double min_output = std::numeric_limits<double>::lowest();
  double max_output = std::numeric_limits<double>::max();
  if (GetSlewNeg() < -1.0) {
    min_output = GetLastOutput() + GetSlewNeg() * GetSampleTime();
  }
  if (GetSlewPos() > 1.0) {
    max_output = GetLastOutput() + GetSlewPos() * GetSampleTime();
  }
  output = std::clamp(output, min_output, max_output);

  if (enable_calculation_log) {
    LOG(WARNING)
        << "[Thermal Debug]: "
        << absl::StrFormat(
               "Slew rate clamped DFF output: %lf (slew_neg: %lf, slew_pos: "
               "%lf); last output: %lf",
               output, GetSlewNeg(), GetSlewPos(), GetLastOutput());
  }

  SetLastOutput(output);

  return output;
}

}  // namespace thermal
}  // namespace milotic_tlbmc
