#include "tlbmc/collector/thermal_collector.h"

#include <algorithm>
#include <atomic>
#include <chrono>  // NOLINT
#include <cstdint>
#include <memory>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "absl/base/nullability.h"
#include "absl/container/flat_hash_map.h"
#include "absl/log/log.h"
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "g3/macros.h"
#include "thread/thread.h"
#include <nlohmann/json_fwd.hpp>
#include "tlbmc/collector/fru_collector.h"
#include "tlbmc/collector/sensor_collector_aggregator.h"
#include "tlbmc/configs/entity_config.h"
#include "thermal_config.pb.h"
#include "tlbmc/thermal/controller/algorithm/dff.h"
#include "tlbmc/thermal/controller/algorithm/eat.h"
#include "tlbmc/thermal/controller/algorithm/first_order_adrc.h"
#include "tlbmc/thermal/controller/algorithm/pid.h"
#include "tlbmc/thermal/controller/algorithm/second_order_adrc.h"
#include "tlbmc/thermal/controller/algorithm/stepwise.h"
#include "tlbmc/thermal/controller/controller.h"
#include "tlbmc/thermal/controller/dff_controller.h"
#include "tlbmc/thermal/controller/eat_controller.h"
#include "tlbmc/thermal/controller/fan_pid_controller.h"
#include "tlbmc/thermal/controller/first_order_adrc_controller.h"
#include "tlbmc/thermal/controller/optimizer/pid/frequency_response_estimation/frequency_response_estimation.h"
#include "tlbmc/thermal/controller/optimizer/pid/pid_optimizer.h"
#include "tlbmc/thermal/controller/optimizer/pid/ziegler_nichols/differentiated_ziegler_nichols.h"
#include "tlbmc/thermal/controller/optimizer/pid/ziegler_nichols/ziegler_nichols.h"
#include "tlbmc/thermal/controller/pid_controller.h"
#include "tlbmc/thermal/controller/second_order_adrc_controller.h"
#include "tlbmc/thermal/controller/stepwise_controller.h"
#include "tlbmc/thermal/debug_mode.h"
#include "tlbmc/thermal/zone_manager.h"

namespace milotic_tlbmc {

absl::flat_hash_map<std::string, thermal::FirstOrderAdrcController*>
ThermalCollector::
    LinkFirstOrderAdrcControllerToZoneAndCreateIdToControllerMap() {
  absl::flat_hash_map<std::string, thermal::FirstOrderAdrcController*>
      controller_id_to_first_order_adrc_controller;
  for (const auto& [zone_id_and_controller_id, first_order_adrc_controller] :
       zone_id_and_controller_id_to_first_order_adrc_controller_) {
    const auto& [zone_id, controller_id] = zone_id_and_controller_id;
    first_order_adrc_controller->GetZoneManager()->AddThermalController(
        controller_id, first_order_adrc_controller.get());

    LOG(WARNING) << absl::StrFormat(
        "1st-order ADRC controller %s linked to zone %d", controller_id,
        zone_id);

    controller_id_to_first_order_adrc_controller.insert(
        {controller_id, first_order_adrc_controller.get()});
  }
  return controller_id_to_first_order_adrc_controller;
}

absl::flat_hash_map<std::string, thermal::SecondOrderAdrcController*>
ThermalCollector::
    LinkSecondOrderAdrcControllerToZoneAndCreateIdToControllerMap() {
  absl::flat_hash_map<std::string, thermal::SecondOrderAdrcController*>
      controller_id_to_second_order_adrc_controller;
  for (const auto& [zone_id_and_controller_id, second_order_adrc_controller] :
       zone_id_and_controller_id_to_second_order_adrc_controller_) {
    const auto& [zone_id, controller_id] = zone_id_and_controller_id;
    second_order_adrc_controller->GetZoneManager()->AddThermalController(
        controller_id, second_order_adrc_controller.get());

    LOG(WARNING) << absl::StrFormat(
        "2nd-order ADRC controller %s linked to zone %d", controller_id,
        zone_id);

    controller_id_to_second_order_adrc_controller.insert(
        {controller_id, second_order_adrc_controller.get()});
  }
  return controller_id_to_second_order_adrc_controller;
}

absl::flat_hash_map<std::string, thermal::PidController*>
ThermalCollector::LinkPidControllerToZoneAndCreateIdToControllerMap() {
  absl::flat_hash_map<std::string, thermal::PidController*>
      controller_id_to_pid_controller;
  for (const auto& [zone_id_and_controller_id, pid_controller] :
       zone_id_and_controller_id_to_pid_controller_) {
    const auto& [zone_id, controller_id] = zone_id_and_controller_id;
    pid_controller->GetZoneManager()->AddThermalController(
        controller_id, pid_controller.get());

    LOG(WARNING) << absl::StrFormat("PID controller %s linked to zone %d",
                                    controller_id, zone_id);

    controller_id_to_pid_controller.insert(
        {controller_id, pid_controller.get()});
  }
  return controller_id_to_pid_controller;
}

absl::flat_hash_map<std::string, thermal::StepwiseController*>
ThermalCollector::LinkStepwiseControllerToZoneAndCreateIdToControllerMap() {
  absl::flat_hash_map<std::string, thermal::StepwiseController*>
      controller_id_to_stepwise_controller;
  for (const auto& [zone_id_and_controller_id, stepwise_controller] :
       zone_id_and_controller_id_to_stepwise_controller_) {
    const auto& [zone_id, controller_id] = zone_id_and_controller_id;
    stepwise_controller->GetZoneManager()->AddThermalController(
        controller_id, stepwise_controller.get());

    LOG(WARNING) << absl::StrFormat("Stepwise controller %s linked to zone %d",
                                    controller_id, zone_id);

    controller_id_to_stepwise_controller.insert(
        {controller_id, stepwise_controller.get()});
  }
  return controller_id_to_stepwise_controller;
}

absl::flat_hash_map<std::string, thermal::FanPidController*>
ThermalCollector::LinkFanPidControllerToZoneAndCreateIdToControllerMap() {
  absl::flat_hash_map<std::string, thermal::FanPidController*>
      controller_id_to_fan_pid_controller;
  for (const auto& [zone_id_and_controller_id, fan_pid_controller] :
       zone_id_and_controller_id_to_fan_pid_controller_) {
    const auto& [zone_id, controller_id] = zone_id_and_controller_id;
    fan_pid_controller->GetZoneManager()->AddThermalController(
        controller_id, fan_pid_controller.get());

    LOG(WARNING) << absl::StrFormat("Fan PID controller %s linked to zone %d",
                                    controller_id, zone_id);

    controller_id_to_fan_pid_controller.insert(
        {controller_id, fan_pid_controller.get()});
  }
  return controller_id_to_fan_pid_controller;
}

absl::flat_hash_map<std::string, thermal::DffController*>
ThermalCollector::LinkDffControllerToZoneAndCreateIdToControllerMap() {
  absl::flat_hash_map<std::string, thermal::DffController*>
      controller_id_to_dff_controller;
  for (const auto& [zone_id_and_controller_id, dff_controller] :
       zone_id_and_controller_id_to_dff_controller_) {
    const auto& [zone_id, controller_id] = zone_id_and_controller_id;
    dff_controller->GetZoneManager()->AddThermalController(
        controller_id, dff_controller.get());

    LOG(WARNING) << absl::StrFormat("DFF controller %s linked to zone %d",
                                    controller_id, zone_id);

    controller_id_to_dff_controller.insert(
        {controller_id, dff_controller.get()});
  }
  return controller_id_to_dff_controller;
}

absl::flat_hash_map<std::string, thermal::EatController*>
ThermalCollector::LinkEatControllerToZoneAndCreateIdToControllerMap() {
  absl::flat_hash_map<std::string, thermal::EatController*>
      controller_id_to_eat_controller;
  for (const auto& [zone_id_and_controller_id, eat_controller] :
       zone_id_and_controller_id_to_eat_controller_) {
    const auto& [zone_id, controller_id] = zone_id_and_controller_id;
    eat_controller->GetZoneManager()->AddThermalController(
        controller_id, eat_controller.get());

    std::vector<thermal::ZoneManager*> affected_zones;
    affected_zones.reserve(eat_controller->GetAffectedZoneIds().size());
    for (int affected_zone_id : eat_controller->GetAffectedZoneIds()) {
      auto zone_manager = zone_id_to_zone_manager_.find(affected_zone_id);
      if (zone_manager == zone_id_to_zone_manager_.end()) {
        LOG(ERROR) << absl::StrFormat("Zone %d not found for EAT controller %s",
                                      affected_zone_id, controller_id);
        continue;
      }
      affected_zones.push_back(zone_manager->second.get());
    }
    if (!eat_controller->SetAffectedZones(std::move(affected_zones)).ok()) {
      LOG(ERROR) << absl::StrFormat(
          "Failed to set affected zones for EAT controller %s", controller_id);
    }

    LOG(WARNING) << absl::StrFormat("EAT controller %s linked to zone %d",
                                    controller_id, zone_id);

    controller_id_to_eat_controller.insert(
        {controller_id, eat_controller.get()});
  }
  return controller_id_to_eat_controller;
}

ThermalCollector::ThermalCollector(
    absl::flat_hash_map<std::tuple<int, std::string>,
                        std::unique_ptr<thermal::FirstOrderAdrcController>>&&
        zone_id_and_controller_id_to_first_order_adrc_controller,
    absl::flat_hash_map<std::tuple<int, std::string>,
                        std::unique_ptr<thermal::SecondOrderAdrcController>>&&
        zone_id_and_controller_id_to_second_order_adrc_controller,
    absl::flat_hash_map<int, std::unique_ptr<thermal::ZoneManager>>&&
        zone_id_to_zone_manager,
    absl::flat_hash_map<std::tuple<int, std::string>,
                        std::unique_ptr<thermal::PidController>>&&
        zone_id_and_controller_id_to_pid_controller,
    absl::flat_hash_map<std::tuple<int, std::string>,
                        std::unique_ptr<thermal::StepwiseController>>&&
        zone_id_and_controller_id_to_stepwise_controller,
    absl::flat_hash_map<std::tuple<int, std::string>,
                        std::unique_ptr<thermal::FanPidController>>&&
        zone_id_and_controller_id_to_fan_pid_controller,
    absl::flat_hash_map<std::tuple<int, std::string>,
                        std::unique_ptr<thermal::DffController>>&&
        zone_id_and_controller_id_to_dff_controller,
    absl::flat_hash_map<std::string, std::vector<int>>&&
        controller_id_to_zone_ids,
    absl::flat_hash_map<int, std::unique_ptr<thermal::ZoneManager>>&&
        zone_id_to_supportive_zone_manager,
    absl::flat_hash_map<std::tuple<int, std::string>,
                        std::unique_ptr<thermal::EatController>>&&
        zone_id_and_controller_id_to_eat_controller,
    std::unique_ptr<ThermalThreadManager> thermal_thread_manager,
    ecclesia::ThreadFactoryInterface* thread_factory)
    : zone_id_to_zone_manager_(std::move(zone_id_to_zone_manager)),
      zone_id_and_controller_id_to_first_order_adrc_controller_(
          std::move(zone_id_and_controller_id_to_first_order_adrc_controller)),
      zone_id_and_controller_id_to_second_order_adrc_controller_(
          std::move(zone_id_and_controller_id_to_second_order_adrc_controller)),
      zone_id_and_controller_id_to_pid_controller_(
          std::move(zone_id_and_controller_id_to_pid_controller)),
      zone_id_and_controller_id_to_stepwise_controller_(
          std::move(zone_id_and_controller_id_to_stepwise_controller)),
      zone_id_and_controller_id_to_fan_pid_controller_(
          std::move(zone_id_and_controller_id_to_fan_pid_controller)),
      zone_id_and_controller_id_to_dff_controller_(
          std::move(zone_id_and_controller_id_to_dff_controller)),
      controller_id_to_zone_ids_(std::move(controller_id_to_zone_ids)),
      zone_id_to_supportive_zone_manager_(
          std::move(zone_id_to_supportive_zone_manager)),
      zone_id_and_controller_id_to_eat_controller_(
          std::move(zone_id_and_controller_id_to_eat_controller)),
      // Link thermal controllers to their zone managers.
      // Initialize maps for ControllerIdToController.
      controller_id_to_controller_({
          .controller_id_to_first_order_adrc_controller =
              LinkFirstOrderAdrcControllerToZoneAndCreateIdToControllerMap(),
          .controller_id_to_second_order_adrc_controller =
              LinkSecondOrderAdrcControllerToZoneAndCreateIdToControllerMap(),
          .controller_id_to_pid_controller =
              LinkPidControllerToZoneAndCreateIdToControllerMap(),
          .controller_id_to_stepwise_controller =
              LinkStepwiseControllerToZoneAndCreateIdToControllerMap(),
          .controller_id_to_fan_pid_controller =
              LinkFanPidControllerToZoneAndCreateIdToControllerMap(),
          .controller_id_to_dff_controller =
              LinkDffControllerToZoneAndCreateIdToControllerMap(),
          .controller_id_to_eat_controller =
              LinkEatControllerToZoneAndCreateIdToControllerMap(),
      }),
      thermal_thread_manager_(std::move(thermal_thread_manager)),
      thread_factory_(thread_factory) {}

ThermalCollector::~ThermalCollector() {
  StopThermalControl();

  // In the case of EmptySensorCollector, avoid dereferencing nullptr.
  if (thermal_thread_manager_ == nullptr) {
    return;
  }

  thermal_thread_manager_->task_scheduler->Stop();
  thermal_thread_manager_->work_guards.clear();

  thermal_control_timers_.clear();

  for (const std::shared_ptr<boost::asio::io_context>& io_context :
       thermal_thread_manager_->io_contexts) {
    io_context->stop();
  }

  for (const std::unique_ptr<ecclesia::ThreadInterface>& thread :
       thermal_thread_manager_->threads) {
    thread->Join();
  }
}

absl::StatusOr<std::unique_ptr<ThermalCollector>> ThermalCollector::Create(
    const Params& params, SensorCollectorAggregator* absl_nonnull aggregator,
    FruCollector* absl_nonnull fru_collector,
    EntityConfig* absl_nonnull entity_config) {
  auto thermal_thread_manager =
      std::make_unique<ThermalThreadManager>(params.clock);

  auto io_context = std::make_shared<boost::asio::io_context>();
  thermal_thread_manager->io_contexts.push_back(io_context);
  thermal_thread_manager->work_guards.push_back(
      boost::asio::make_work_guard(*io_context));

  bool tuning_enabled = params.tuning_enabled;
  uint32_t failsafe_log_count_per_sec =
      params.failsafe_logger_config.failsafe_log_limit_per_second();
  if (failsafe_log_count_per_sec < 1) {
    failsafe_log_count_per_sec = 20;
  }
  std::string sample_data_file_prefix = params.sample_data_file_prefix;

  absl::flat_hash_map<std::string, std::vector<int>> controller_id_to_zone_ids;

  // Create zone managers.
  absl::flat_hash_map<int, std::unique_ptr<thermal::ZoneManager>>
      zone_id_to_zone_manager;
  for (const ZoneManagerConfig& zone_config :
       params.zone_manager_configs.zone_manager_configs()) {
    ECCLESIA_ASSIGN_OR_RETURN(
        std::unique_ptr<thermal::ZoneManager> zone_manager,
        thermal::ZoneManager::Create({
            .id = zone_config.id(),
            .ms_per_fan_cycle = zone_config.ms_per_fan_cycle(),
            .ms_per_thermal_cycle = zone_config.ms_per_thermal_cycle(),
            .failsafe_log_count_per_sec = failsafe_log_count_per_sec,
            .debug_mode = thermal::DebugMode(
                zone_config.debug_mode().debug_enabled(),
                zone_config.debug_mode().debug_pid_enabled(),
                zone_config.debug_mode().debug_dff_enabled(), tuning_enabled),
            .aggregator = aggregator,
            .fru_collector = fru_collector,
            .entity_config = entity_config,
            .zone_failsafe_percent = zone_config.zone_failsafe_percent(),
            .setpoint_upper_bound = zone_config.setpoint_upper_bound(),
            .setpoint_lower_bound = zone_config.setpoint_lower_bound(),
            .minimum_thermal_setpoint = zone_config.minimum_thermal_setpoint(),
            .input_sensors = {zone_config.input_sensors().begin(),
                              zone_config.input_sensors().end()},
            .output_fans = {zone_config.output_fans().begin(),
                            zone_config.output_fans().end()},
            .sample_data_file_prefix = sample_data_file_prefix,
        }));

    LOG(WARNING) << absl::StrFormat("Zone manager %d created",
                                    zone_manager->GetId());

    zone_id_to_zone_manager[zone_config.id()] = std::move(zone_manager);
  }

  // Create 1st-order ADRC controllers.
  absl::flat_hash_map<std::tuple<int, std::string>,
                      std::unique_ptr<thermal::FirstOrderAdrcController>>
      zone_id_and_controller_id_to_first_order_adrc_controller;
  for (const FirstOrderAdrcControllerConfig& adrc_config :
       params.first_order_adrc_controller_configs
           .first_order_adrc_controller_configs()) {
    for (int zone_id : adrc_config.zone_manager_id()) {
      FirstOrderAdrcLoopConfig adrc_loop_config =
          adrc_config.first_order_adrc_loop_config();

      auto adrc_loop = std::make_unique<thermal::FirstOrderAdrcThermalLoop>(
          adrc_loop_config);

      ECCLESIA_ASSIGN_OR_RETURN(
          std::unique_ptr<thermal::FirstOrderAdrcController> adrc_controller,
          thermal::FirstOrderAdrcController::Create({
              .id = adrc_config.id(),
              .zone_manager = zone_id_to_zone_manager[zone_id].get(),
              .first_order_adrc_loop = std::move(adrc_loop),
              .setpoint = adrc_config.setpoint(),
              .input_sensors = {adrc_config.input_sensors().begin(),
                                adrc_config.input_sensors().end()},
          }));

      LOG(WARNING) << absl::StrFormat(
          "1st-order ADRC controller %s created for zone %d",
          adrc_controller->GetId(), zone_id);

      controller_id_to_zone_ids[adrc_controller->GetId()].push_back(
          adrc_controller->GetZoneManager()->GetId());
      zone_id_and_controller_id_to_first_order_adrc_controller[std::make_tuple(
          zone_id, adrc_controller->GetId())] = std::move(adrc_controller);
    }
  }

  // Create 2nd-order ADRC controllers.
  absl::flat_hash_map<std::tuple<int, std::string>,
                      std::unique_ptr<thermal::SecondOrderAdrcController>>
      zone_id_and_controller_id_to_second_order_adrc_controller;
  for (const SecondOrderAdrcControllerConfig& adrc_config :
       params.second_order_adrc_controller_configs
           .second_order_adrc_controller_configs()) {
    for (int zone_id : adrc_config.zone_manager_id()) {
      SecondOrderAdrcLoopConfig adrc_loop_config =
          adrc_config.second_order_adrc_loop_config();

      std::vector<thermal::DisturbanceFactors> disturbance_factors;
      std::vector<std::vector<std::string>> disturbance_sensor_lists;
      for (const QuantifiableDisturbance& quantifiable_disturbance :
           adrc_config.quantifiable_disturbances()) {
        disturbance_factors.push_back(thermal::DisturbanceFactors{
            .d = quantifiable_disturbance.d(),
            .reference_setpoint =
                quantifiable_disturbance.reference_setpoint()});

        std::vector<std::string> disturbance_sensor_list(
            quantifiable_disturbance.input_sensors().begin(),
            quantifiable_disturbance.input_sensors().end());
        disturbance_sensor_lists.push_back(disturbance_sensor_list);
      }

      auto adrc_loop = std::make_unique<thermal::SecondOrderAdrcThermalLoop>(
          adrc_loop_config, disturbance_factors);

      ECCLESIA_ASSIGN_OR_RETURN(
          std::unique_ptr<thermal::SecondOrderAdrcController> adrc_controller,
          thermal::SecondOrderAdrcController::Create({
              .id = adrc_config.id(),
              .zone_manager = zone_id_to_zone_manager[zone_id].get(),
              .second_order_adrc_loop = std::move(adrc_loop),
              .setpoint = adrc_config.setpoint(),
              .input_sensors = {adrc_config.input_sensors().begin(),
                                adrc_config.input_sensors().end()},
              .disturbance_sensor_lists = std::move(disturbance_sensor_lists),
          }));

      LOG(WARNING) << absl::StrFormat(
          "2nd-order ADRC controller %s created for zone %d",
          adrc_controller->GetId(), zone_id);

      controller_id_to_zone_ids[adrc_controller->GetId()].push_back(
          adrc_controller->GetZoneManager()->GetId());
      zone_id_and_controller_id_to_second_order_adrc_controller[std::make_tuple(
          zone_id, adrc_controller->GetId())] = std::move(adrc_controller);
    }
  }

  // Create PID controllers.
  absl::flat_hash_map<std::tuple<int, std::string>,
                      std::unique_ptr<thermal::PidController>>
      zone_id_and_controller_id_to_pid_controller;
  for (const PidControllerConfig& pid_config :
       params.pid_controller_configs.pid_controller_configs()) {
    for (int zone_id : pid_config.zone_manager_id()) {
      auto pid_loop = std::make_unique<thermal::PidThermalLoop>(
          pid_config.pid_loop_config());
      thermal::PidOptimizerInfo pid_optimizer_info;
      if (pid_config.has_pid_autotuner_config()) {
        ECCLESIA_ASSIGN_OR_RETURN(thermal::PidOptimizerInfo tuner,
                                  CreatePidAutoTuner(pid_config));
        pid_optimizer_info = std::move(tuner);
      }

      ECCLESIA_ASSIGN_OR_RETURN(
          std::unique_ptr<thermal::PidController> pid_controller,
          thermal::PidController::Create({
              .id = pid_config.id(),
              .zone_manager = zone_id_to_zone_manager[zone_id].get(),
              .pid_loop = std::move(pid_loop),
              .setpoint = pid_config.setpoint(),
              .input_process_type = pid_config.input_process_type(),
              .input_sensors = {pid_config.input_sensors().begin(),
                                pid_config.input_sensors().end()},
              .pid_optimizer_info = std::move(pid_optimizer_info),
          }));

      LOG(WARNING) << absl::StrFormat("PID controller %s created for zone %d",
                                      pid_controller->GetId(), zone_id);

      controller_id_to_zone_ids[pid_controller->GetId()].push_back(
          pid_controller->GetZoneManager()->GetId());
      zone_id_and_controller_id_to_pid_controller[std::make_tuple(
          zone_id, pid_controller->GetId())] = std::move(pid_controller);
    }
  }

  // Create stepwise controllers.
  absl::flat_hash_map<std::tuple<int, std::string>,
                      std::unique_ptr<thermal::StepwiseController>>
      zone_id_and_controller_id_to_stepwise_controller;
  for (const StepwiseControllerConfig& stepwise_config :
       params.stepwise_controller_configs.stepwise_controller_configs()) {
    for (int zone_id : stepwise_config.zone_manager_id()) {
      auto stepwise_loop = std::make_unique<thermal::StepwiseThermalLoop>(
          stepwise_config.stepwise_loop_config());

      ECCLESIA_ASSIGN_OR_RETURN(
          std::unique_ptr<thermal::StepwiseController> stepwise_controller,
          thermal::StepwiseController::Create({
              .id = stepwise_config.id(),
              .zone_manager = zone_id_to_zone_manager[zone_id].get(),
              .stepwise_loop = std::move(stepwise_loop),
              .input_sensors = {stepwise_config.input_sensors().begin(),
                                stepwise_config.input_sensors().end()},
              .is_ceiling = stepwise_config.is_ceiling(),
          }));

      LOG(WARNING) << absl::StrFormat(
          "Stepwise controller %s created for zone %d",
          stepwise_controller->GetId(), zone_id);

      controller_id_to_zone_ids[stepwise_controller->GetId()].push_back(
          stepwise_controller->GetZoneManager()->GetId());
      zone_id_and_controller_id_to_stepwise_controller[std::make_tuple(
          zone_id, stepwise_controller->GetId())] =
          std::move(stepwise_controller);
    }
  }

  // Create fan PID controllers.
  absl::flat_hash_map<std::tuple<int, std::string>,
                      std::unique_ptr<thermal::FanPidController>>
      zone_id_and_controller_id_to_fan_pid_controller;
  for (const FanPidControllerConfig& fan_pid_config :
       params.fan_pid_controller_configs.fan_pid_controller_configs()) {
    for (int zone_id : fan_pid_config.zone_manager_id()) {
      auto pid_loop = std::make_unique<thermal::PidThermalLoop>(
          fan_pid_config.pid_loop_config());

      ECCLESIA_ASSIGN_OR_RETURN(
          std::unique_ptr<thermal::FanPidController> fan_pid_controller,
          thermal::FanPidController::Create({
              .id = fan_pid_config.id(),
              .zone_manager = zone_id_to_zone_manager[zone_id].get(),
              .pid_loop = std::move(pid_loop),
              .input_fans = {fan_pid_config.input_fans().begin(),
                             fan_pid_config.input_fans().end()},
              .output_fans = {fan_pid_config.output_fans().begin(),
                              fan_pid_config.output_fans().end()},
          }));

      LOG(WARNING) << absl::StrFormat(
          "Fan PID controller %s created for zone %d",
          fan_pid_controller->GetId(), zone_id);

      controller_id_to_zone_ids[fan_pid_controller->GetId()].push_back(
          fan_pid_controller->GetZoneManager()->GetId());
      zone_id_and_controller_id_to_fan_pid_controller[std::make_tuple(
          zone_id, fan_pid_controller->GetId())] =
          std::move(fan_pid_controller);
    }
  }

  // Create DFF controllers.
  absl::flat_hash_map<std::tuple<int, std::string>,
                      std::unique_ptr<thermal::DffController>>
      zone_id_and_controller_id_to_dff_controller;
  for (const DffControllerConfig& dff_config :
       params.dff_controller_configs.dff_controller_configs()) {
    for (int zone_id : dff_config.zone_manager_id()) {
      auto dff_loop = std::make_unique<thermal::DffThermalLoop>(
          dff_config.dff_loop_config());

      ECCLESIA_ASSIGN_OR_RETURN(
          std::unique_ptr<thermal::DffController> dff_controller,
          thermal::DffController::Create({
              .id = dff_config.id(),
              .zone_manager = zone_id_to_zone_manager[zone_id].get(),
              .dff_loop = std::move(dff_loop),
              .input_sensors = {dff_config.input_sensors().begin(),
                                dff_config.input_sensors().end()},
              .affected_controller_ids =
                  {dff_config.affected_controller_ids().begin(),
                   dff_config.affected_controller_ids().end()},
          }));

      LOG(WARNING) << absl::StrFormat("DFF controller %s created for zone %d",
                                      dff_controller->GetId(), zone_id);

      controller_id_to_zone_ids[dff_controller->GetId()].push_back(
          dff_controller->GetZoneManager()->GetId());
      zone_id_and_controller_id_to_dff_controller[std::make_tuple(
          zone_id, dff_controller->GetId())] = std::move(dff_controller);
    }
  }

  // Create supportive zone managers.
  absl::flat_hash_map<int, std::unique_ptr<thermal::ZoneManager>>
      zone_id_to_supportive_zone_manager;
  for (const SupportiveZoneManagerConfig& zone_config :
       params.supportive_zone_manager_configs
           .supportive_zone_manager_configs()) {
    ECCLESIA_ASSIGN_OR_RETURN(
        std::unique_ptr<thermal::ZoneManager> supportive_zone_manager,
        thermal::ZoneManager::Create({
            .id = zone_config.id(),
            .ms_per_thermal_cycle = zone_config.ms_per_thermal_cycle(),
            .debug_mode = thermal::DebugMode(
                zone_config.debug_mode().debug_enabled(),
                zone_config.debug_mode().debug_pid_enabled(),
                zone_config.debug_mode().debug_dff_enabled(), tuning_enabled),
            .aggregator = aggregator,
            .fru_collector = fru_collector,
            .entity_config = entity_config,
            .input_sensors = {zone_config.input_sensors().begin(),
                              zone_config.input_sensors().end()},
            .sample_data_file_prefix = sample_data_file_prefix,
        }));

    LOG(WARNING) << absl::StrFormat("Supportive zone manager %d created",
                                    supportive_zone_manager->GetId());

    zone_id_to_supportive_zone_manager[zone_config.id()] =
        std::move(supportive_zone_manager);
  }

  // Create EAT controllers.
  absl::flat_hash_map<std::tuple<int, std::string>,
                      std::unique_ptr<thermal::EatController>>
      zone_id_and_controller_id_to_eat_controller;
  for (const EatControllerConfig& eat_config :
       params.eat_controller_configs.eat_controller_configs()) {
    for (int zone_id : eat_config.zone_manager_id()) {
      auto eat_loop = std::make_unique<thermal::EatThermalLoop>(
          eat_config.eat_loop_config());

      ECCLESIA_ASSIGN_OR_RETURN(
          std::unique_ptr<thermal::EatController> eat_controller,
          thermal::EatController::Create({
              .id = eat_config.id(),
              .zone_manager = zone_id_to_supportive_zone_manager[zone_id].get(),
              .eat_loop = std::move(eat_loop),
              .input_sensors = {eat_config.input_sensors().begin(),
                                eat_config.input_sensors().end()},
              .affected_zone_ids = {eat_config.affected_zone_ids().begin(),
                                    eat_config.affected_zone_ids().end()},
          }));

      LOG(WARNING) << absl::StrFormat("EAT controller %s created for zone %d",
                                      eat_controller->GetId(), zone_id);

      controller_id_to_zone_ids[eat_controller->GetId()].push_back(
          eat_controller->GetZoneManager()->GetId());
      zone_id_and_controller_id_to_eat_controller[std::make_tuple(
          zone_id, eat_controller->GetId())] = std::move(eat_controller);
    }
  }

  return absl::WrapUnique(new ThermalCollector(
      std::move(zone_id_and_controller_id_to_first_order_adrc_controller),
      std::move(zone_id_and_controller_id_to_second_order_adrc_controller),
      std::move(zone_id_to_zone_manager),
      std::move(zone_id_and_controller_id_to_pid_controller),
      std::move(zone_id_and_controller_id_to_stepwise_controller),
      std::move(zone_id_and_controller_id_to_fan_pid_controller),
      std::move(zone_id_and_controller_id_to_dff_controller),
      std::move(controller_id_to_zone_ids),
      std::move(zone_id_to_supportive_zone_manager),
      std::move(zone_id_and_controller_id_to_eat_controller),
      std::move(thermal_thread_manager), params.thread_factory));
}

std::vector<const thermal::ZoneManager*> ThermalCollector::GetAllThermalZones()
    const {
  std::vector<const thermal::ZoneManager*> thermal_zones;
  thermal_zones.reserve(zone_id_to_zone_manager_.size() +
                        zone_id_to_supportive_zone_manager_.size());
  for (const auto& [zone_id, zone_manager] : zone_id_to_zone_manager_) {
    thermal_zones.push_back(zone_manager.get());
  }
  for (const auto& [zone_id, zone_manager] :
       zone_id_to_supportive_zone_manager_) {
    thermal_zones.push_back(zone_manager.get());
  }
  std::sort(thermal_zones.begin(), thermal_zones.end(),
            [](const thermal::ZoneManager* a, const thermal::ZoneManager* b) {
              return a->GetId() < b->GetId();
            });
  return thermal_zones;
}

std::vector<const thermal::FirstOrderAdrcController*>
ThermalCollector::GetAllFirstOrderAdrcControllers() const {
  std::vector<const thermal::FirstOrderAdrcController*>
      first_order_adrc_controllers;
  first_order_adrc_controllers.reserve(
      controller_id_to_controller_.controller_id_to_first_order_adrc_controller
          .size());
  for (const auto& [controller_id, first_order_adrc_controller] :
       controller_id_to_controller_
           .controller_id_to_first_order_adrc_controller) {
    first_order_adrc_controllers.push_back(first_order_adrc_controller);
  }
  std::sort(first_order_adrc_controllers.begin(),
            first_order_adrc_controllers.end(),
            [](const thermal::FirstOrderAdrcController* a,
               const thermal::FirstOrderAdrcController* b) {
              return a->GetId() < b->GetId();
            });
  return first_order_adrc_controllers;
}

std::vector<const thermal::SecondOrderAdrcController*>
ThermalCollector::GetAllSecondOrderAdrcControllers() const {
  std::vector<const thermal::SecondOrderAdrcController*>
      second_order_adrc_controllers;
  second_order_adrc_controllers.reserve(
      controller_id_to_controller_.controller_id_to_second_order_adrc_controller
          .size());
  for (const auto& [controller_id, second_order_adrc_controller] :
       controller_id_to_controller_
           .controller_id_to_second_order_adrc_controller) {
    second_order_adrc_controllers.push_back(second_order_adrc_controller);
  }
  std::sort(second_order_adrc_controllers.begin(),
            second_order_adrc_controllers.end(),
            [](const thermal::SecondOrderAdrcController* a,
               const thermal::SecondOrderAdrcController* b) {
              return a->GetId() < b->GetId();
            });
  return second_order_adrc_controllers;
}

std::vector<const thermal::PidController*>
ThermalCollector::GetAllPidControllers() const {
  std::vector<const thermal::PidController*> pid_controllers;
  pid_controllers.reserve(
      controller_id_to_controller_.controller_id_to_pid_controller.size());
  for (const auto& [controller_id, pid_controller] :
       controller_id_to_controller_.controller_id_to_pid_controller) {
    pid_controllers.push_back(pid_controller);
  }
  std::sort(
      pid_controllers.begin(), pid_controllers.end(),
      [](const thermal::PidController* a, const thermal::PidController* b) {
        return a->GetId() < b->GetId();
      });
  return pid_controllers;
}

std::vector<const thermal::StepwiseController*>
ThermalCollector::GetAllStepwiseControllers() const {
  std::vector<const thermal::StepwiseController*> stepwise_controllers;
  stepwise_controllers.reserve(
      controller_id_to_controller_.controller_id_to_stepwise_controller.size());
  for (const auto& [controller_id, stepwise_controller] :
       controller_id_to_controller_.controller_id_to_stepwise_controller) {
    stepwise_controllers.push_back(stepwise_controller);
  }
  std::sort(stepwise_controllers.begin(), stepwise_controllers.end(),
            [](const thermal::StepwiseController* a,
               const thermal::StepwiseController* b) {
              return a->GetId() < b->GetId();
            });
  return stepwise_controllers;
}

std::vector<const thermal::FanPidController*>
ThermalCollector::GetAllFanPidControllers() const {
  std::vector<const thermal::FanPidController*> fan_pid_controllers;
  fan_pid_controllers.reserve(
      controller_id_to_controller_.controller_id_to_fan_pid_controller.size());
  for (const auto& [controller_id, fan_pid_controller] :
       controller_id_to_controller_.controller_id_to_fan_pid_controller) {
    fan_pid_controllers.push_back(fan_pid_controller);
  }
  std::sort(fan_pid_controllers.begin(), fan_pid_controllers.end(),
            [](const thermal::FanPidController* a,
               const thermal::FanPidController* b) {
              return a->GetId() < b->GetId();
            });
  return fan_pid_controllers;
}

std::vector<const thermal::DffController*>
ThermalCollector::GetAllDffControllers() const {
  std::vector<const thermal::DffController*> dff_controllers;
  dff_controllers.reserve(
      controller_id_to_controller_.controller_id_to_dff_controller.size());
  for (const auto& [controller_id, dff_controller] :
       controller_id_to_controller_.controller_id_to_dff_controller) {
    dff_controllers.push_back(dff_controller);
  }
  std::sort(
      dff_controllers.begin(), dff_controllers.end(),
      [](const thermal::DffController* a, const thermal::DffController* b) {
        return a->GetId() < b->GetId();
      });
  return dff_controllers;
}

std::vector<const thermal::EatController*>
ThermalCollector::GetAllEatControllers() const {
  std::vector<const thermal::EatController*> eat_controllers;
  eat_controllers.reserve(
      controller_id_to_controller_.controller_id_to_eat_controller.size());
  for (const auto& [controller_id, eat_controller] :
       controller_id_to_controller_.controller_id_to_eat_controller) {
    eat_controllers.push_back(eat_controller);
  }
  std::sort(
      eat_controllers.begin(), eat_controllers.end(),
      [](const thermal::EatController* a, const thermal::EatController* b) {
        return a->GetId() < b->GetId();
      });
  return eat_controllers;
}

absl::StatusOr<const thermal::ZoneManager*>
ThermalCollector::GetThermalZoneById(int zone_id) const {
  // First check if the zone is a non-supportive zone.
  auto itr_zone_manager = zone_id_to_zone_manager_.find(zone_id);
  // If not, check if the zone is a supportive zone.
  auto itr_supportive_zone_manager =
      zone_id_to_supportive_zone_manager_.find(zone_id);
  if (itr_zone_manager == zone_id_to_zone_manager_.end() &&
      itr_supportive_zone_manager ==
          zone_id_to_supportive_zone_manager_.end()) {
    return absl::NotFoundError(
        absl::StrCat("Zone with id ", zone_id, " not found"));
  }
  return itr_zone_manager != zone_id_to_zone_manager_.end()
             ? itr_zone_manager->second.get()
             : itr_supportive_zone_manager->second.get();
}

absl::StatusOr<const thermal::FirstOrderAdrcController*>
ThermalCollector::GetFirstOrderAdrcControllerById(
    absl::string_view controller_id) const {
  auto itr =
      controller_id_to_controller_.controller_id_to_first_order_adrc_controller
          .find(controller_id);
  if (itr == controller_id_to_controller_
                 .controller_id_to_first_order_adrc_controller.end()) {
    return absl::NotFoundError(absl::StrCat("FirstOrderAdrcController with id ",
                                            controller_id, " not found"));
  }
  return itr->second;
}

absl::StatusOr<const thermal::SecondOrderAdrcController*>
ThermalCollector::GetSecondOrderAdrcControllerById(
    absl::string_view controller_id) const {
  auto itr =
      controller_id_to_controller_.controller_id_to_second_order_adrc_controller
          .find(controller_id);
  if (itr == controller_id_to_controller_
                 .controller_id_to_second_order_adrc_controller.end()) {
    return absl::NotFoundError(absl::StrCat(
        "SecondOrderAdrcController with id ", controller_id, " not found"));
  }
  return itr->second;
}

absl::StatusOr<const thermal::PidController*>
ThermalCollector::GetPidControllerById(absl::string_view controller_id) const {
  auto itr = controller_id_to_controller_.controller_id_to_pid_controller.find(
      controller_id);
  if (itr ==
      controller_id_to_controller_.controller_id_to_pid_controller.end()) {
    return absl::NotFoundError(
        absl::StrCat("PidController with id ", controller_id, " not found"));
  }
  return itr->second;
}

absl::StatusOr<const thermal::StepwiseController*>
ThermalCollector::GetStepwiseControllerById(
    absl::string_view controller_id) const {
  auto itr =
      controller_id_to_controller_.controller_id_to_stepwise_controller.find(
          controller_id);
  if (itr ==
      controller_id_to_controller_.controller_id_to_stepwise_controller.end()) {
    return absl::NotFoundError(absl::StrCat("StepwiseController with id ",
                                            controller_id, " not found"));
  }
  return itr->second;
}

absl::StatusOr<const thermal::FanPidController*>
ThermalCollector::GetFanPidControllerById(
    absl::string_view controller_id) const {
  auto itr =
      controller_id_to_controller_.controller_id_to_fan_pid_controller.find(
          controller_id);
  if (itr ==
      controller_id_to_controller_.controller_id_to_fan_pid_controller.end()) {
    return absl::NotFoundError(
        absl::StrCat("FanPidController with id ", controller_id, " not found"));
  }
  return itr->second;
}

absl::StatusOr<const thermal::DffController*>
ThermalCollector::GetDffControllerById(absl::string_view controller_id) const {
  auto itr = controller_id_to_controller_.controller_id_to_dff_controller.find(
      controller_id);
  if (itr ==
      controller_id_to_controller_.controller_id_to_dff_controller.end()) {
    return absl::NotFoundError(
        absl::StrCat("DffController with id ", controller_id, " not found"));
  }
  return itr->second;
}

absl::StatusOr<const thermal::EatController*>
ThermalCollector::GetEatControllerById(absl::string_view controller_id) const {
  auto itr = controller_id_to_controller_.controller_id_to_eat_controller.find(
      controller_id);
  if (itr ==
      controller_id_to_controller_.controller_id_to_eat_controller.end()) {
    return absl::NotFoundError(
        absl::StrCat("EatController with id ", controller_id, " not found"));
  }
  return itr->second;
}

nlohmann::json ThermalCollector::ToJson() const {
  nlohmann::json::object_t response;

  nlohmann::json::object_t zone_managers;
  for (const auto& [zone_id, zone_manager] : zone_id_to_zone_manager_) {
    nlohmann::json zone_manager_json;
    zone_manager_json["zone_index"] = zone_id;
    zone_manager_json["failsafe_percent"] =
        zone_manager->GetZoneFailsafePercent();
    zone_manager_json["fan_mode"] =
        (zone_manager->GetManualMode() ? "Manual" : "Auto");
    zone_manager_json["min_thermal_output"] =
        zone_manager->GetMinimumThermalSetpoint();

    zone_managers[absl::StrCat("Zone_", zone_id)] =
        std::move(zone_manager_json);
  }
  response["Zones"] = std::move(zone_managers);

  nlohmann::json::object_t pid_controllers;
  for (const auto& [controller_id, pid_controller] :
       controller_id_to_controller_.controller_id_to_pid_controller) {
    nlohmann::json pid_controller_json;
    pid_controller_json["feed_forward_gain"] =
        pid_controller->GetPidLoop()->GetFeedForwardGain();
    pid_controller_json["feed_forward_offset"] =
        pid_controller->GetPidLoop()->GetFeedForwardOffset();
    pid_controller_json["proportional_coefficient"] =
        pid_controller->GetPidLoop()->GetCoeffProportional();
    pid_controller_json["integral_coefficient"] =
        pid_controller->GetPidLoop()->GetCoeffIntegral();
    pid_controller_json["derivative_coefficient"] =
        pid_controller->GetPidLoop()->GetCoeffDerivative();
    pid_controller_json["integral_limit_max"] =
        pid_controller->GetPidLoop()->GetIntegralLimitMax();
    pid_controller_json["integral_limit_min"] =
        pid_controller->GetPidLoop()->GetIntegralLimitMin();
    pid_controller_json["output_limit_max"] =
        pid_controller->GetPidLoop()->GetOutputLimitMax();
    pid_controller_json["output_limit_min"] =
        pid_controller->GetPidLoop()->GetOutputLimitMin();
    pid_controller_json["slew_neg"] =
        pid_controller->GetPidLoop()->GetSlewNeg();
    pid_controller_json["slew_pos"] =
        pid_controller->GetPidLoop()->GetSlewPos();
    pid_controller_json["setpoint"] = pid_controller->GetSetpoint();
    for (const PidControllerSensorInfo& sensor :
         pid_controller->GetInputSensors()) {
      pid_controller_json["input_sensors"].push_back(sensor.sensor_key());
    }
    if (controller_id_to_zone_ids_.contains(controller_id)) {
      pid_controller_json["owner_zone"] =
          controller_id_to_zone_ids_.at(controller_id);
    }

    pid_controllers[controller_id] = std::move(pid_controller_json);
  }
  response["PidControllers"] = std::move(pid_controllers);

  nlohmann::json::object_t fan_pid_controllers;
  for (const auto& [controller_id, fan_pid_controller] :
       controller_id_to_controller_.controller_id_to_fan_pid_controller) {
    nlohmann::json fan_pid_controller_json;
    fan_pid_controller_json["feed_forward_gain"] =
        fan_pid_controller->GetPidLoop()->GetFeedForwardGain();
    fan_pid_controller_json["feed_forward_offset"] =
        fan_pid_controller->GetPidLoop()->GetFeedForwardOffset();
    fan_pid_controller_json["proportional_coefficient"] =
        fan_pid_controller->GetPidLoop()->GetCoeffProportional();
    fan_pid_controller_json["integral_coefficient"] =
        fan_pid_controller->GetPidLoop()->GetCoeffIntegral();
    fan_pid_controller_json["derivative_coefficient"] =
        fan_pid_controller->GetPidLoop()->GetCoeffDerivative();
    fan_pid_controller_json["integral_limit_max"] =
        fan_pid_controller->GetPidLoop()->GetIntegralLimitMax();
    fan_pid_controller_json["integral_limit_min"] =
        fan_pid_controller->GetPidLoop()->GetIntegralLimitMin();
    fan_pid_controller_json["output_limit_max"] =
        fan_pid_controller->GetPidLoop()->GetOutputLimitMax();
    fan_pid_controller_json["output_limit_min"] =
        fan_pid_controller->GetPidLoop()->GetOutputLimitMin();
    fan_pid_controller_json["slew_neg"] =
        fan_pid_controller->GetPidLoop()->GetSlewNeg();
    fan_pid_controller_json["slew_pos"] =
        fan_pid_controller->GetPidLoop()->GetSlewPos();
    for (absl::string_view fan : fan_pid_controller->GetInputFans()) {
      fan_pid_controller_json["input_fans"].push_back(fan);
    }
    for (absl::string_view fan_name : fan_pid_controller->GetOutputFans()) {
      fan_pid_controller_json["output_fans"].push_back(fan_name);
    }
    if (controller_id_to_zone_ids_.contains(controller_id)) {
      fan_pid_controller_json["owner_zone"] =
          controller_id_to_zone_ids_.at(controller_id);
    }

    fan_pid_controllers[controller_id] = std::move(fan_pid_controller_json);
  }
  response["FanPidControllers"] = std::move(fan_pid_controllers);

  nlohmann::json::object_t second_order_adrc_controllers;
  for (const auto& [controller_id, second_order_adrc_controller] :
       controller_id_to_controller_
           .controller_id_to_second_order_adrc_controller) {
    nlohmann::json second_order_adrc_controller_json =
        second_order_adrc_controller->ToJson();
    if (auto it = controller_id_to_zone_ids_.find(controller_id);
        it != controller_id_to_zone_ids_.end()) {
      second_order_adrc_controller_json["owner_zone"] = it->second;
    }

    second_order_adrc_controllers[controller_id] =
        std::move(second_order_adrc_controller_json);
  }
  response["SecondOrderAdrcControllers"] =
      std::move(second_order_adrc_controllers);

  nlohmann::json::object_t first_order_adrc_controllers;
  for (const auto& [controller_id, first_order_adrc_controller] :
       controller_id_to_controller_
           .controller_id_to_first_order_adrc_controller) {
    nlohmann::json first_order_adrc_controller_json =
        first_order_adrc_controller->ToJson();
    if (auto it = controller_id_to_zone_ids_.find(controller_id);
        it != controller_id_to_zone_ids_.end()) {
      first_order_adrc_controller_json["owner_zone"] = it->second;
    }

    first_order_adrc_controllers[controller_id] =
        std::move(first_order_adrc_controller_json);
  }
  response["FirstOrderAdrcControllers"] =
      std::move(first_order_adrc_controllers);

  return response;
}

void ThermalCollector::StartThermalControl() {
  for (const auto& [zone_id, zone_manager] : zone_id_to_zone_manager_) {
    auto timer = std::make_shared<boost::asio::steady_timer>(
        **thermal_thread_manager_->io_contexts.begin());
    thermal_control_timers_.push_back(timer);
    LOG(WARNING) << "Start thermal control for zone `" << zone_id << "`";

    boost::asio::post(**thermal_thread_manager_->io_contexts.begin(),
                      [this, zone_manager = zone_manager.get(), timer] {
                        ProcessThermalControl(
                            zone_manager, timer, /*first_run=*/true,
                            /*ms_elapsed_in_current_cycle=*/0);
                      });
  }
  for (const auto& [zone_id, zone_manager] :
       zone_id_to_supportive_zone_manager_) {
    auto timer = std::make_shared<boost::asio::steady_timer>(
        **thermal_thread_manager_->io_contexts.begin());
    thermal_control_timers_.push_back(timer);
    LOG(WARNING) << "Start thermal control for supportive zone `" << zone_id
                 << "`";

    boost::asio::post(**thermal_thread_manager_->io_contexts.begin(),
                      [this, zone_manager = zone_manager.get(), timer] {
                        ProcessThermalControl(
                            zone_manager, timer, /*first_run=*/true,
                            /*ms_elapsed_in_current_cycle=*/0);
                      });
  }
}

void ThermalCollector::StartCollection() {
  StartThermalControl();

  for (const auto& io_context : thermal_thread_manager_->io_contexts) {
    thermal_thread_manager_->threads.push_back(
        thread_factory_->New([io_context]() { io_context->run(); }));
  }
}

void ThermalCollector::SetManualMode(bool enable) {
  for (const auto& [zone_id, zone_manager] : zone_id_to_zone_manager_) {
    zone_manager->SetManualMode(enable);
    zone_manager->TryLogThermalDebugMessage(
        absl::StrFormat("Zone %d set to manual mode %s.", zone_id,
                        (enable ? "true" : "false")));
  }
}

absl::flat_hash_map<int, bool> ThermalCollector::GetZoneIdToManualModes()
    const {
  absl::flat_hash_map<int, bool> zone_id_to_manual_modes;
  for (const auto& [zone_id, zone_manager] : zone_id_to_zone_manager_) {
    zone_id_to_manual_modes[zone_manager->GetId()] =
        zone_manager->GetManualMode();
  }
  return zone_id_to_manual_modes;
}

void ThermalCollector::SetManualPwm(absl::string_view fan_name, double pwm) {
  for (const auto& [zone_id, zone_manager] : zone_id_to_zone_manager_) {
    zone_manager->SetManualPwm(fan_name, pwm);
  }
}

absl::Status ThermalCollector::RequestPidControllerCoefficientsTuning(
    absl::string_view controller_id,
    const thermal::PidController::PidControllerCoefficients& coefficients) {
  auto pid_controller_it =
      controller_id_to_controller_.controller_id_to_pid_controller.find(
          controller_id);
  if (pid_controller_it ==
      controller_id_to_controller_.controller_id_to_pid_controller.end()) {
    return absl::NotFoundError(
        absl::StrCat("PidController with id ", controller_id, " not found"));
  }
  if (!pid_controller_it->second->GetZoneManager()->GetTuningEnabled()) {
    return absl::InternalError(
        absl::StrCat("Tuning mode is not enabled for the controller ",
                     controller_id, "'s zone."));
  }

  auto zone_ids_it = controller_id_to_zone_ids_.find(controller_id);
  if (zone_ids_it == controller_id_to_zone_ids_.end()) {
    return absl::NotFoundError(absl::StrCat(
        "There is no zone associated with controller ", controller_id));
  }

  absl::MutexLock lock(tuning_mutex_);
  controller_id_to_pending_pid_coefficient_[controller_id] = coefficients;
  for (int zone_id : zone_ids_it->second) {
    zone_ids_with_pending_tuning_request_.insert(zone_id);
  }
  return absl::OkStatus();
}

absl::Status ThermalCollector::RequestFanPidControllerCoefficientsTuning(
    absl::string_view controller_id,
    const thermal::FanPidController::FanPidControllerCoefficients&
        coefficients) {
  auto fan_pid_controller_it =
      controller_id_to_controller_.controller_id_to_fan_pid_controller.find(
          controller_id);
  if (fan_pid_controller_it ==
      controller_id_to_controller_.controller_id_to_fan_pid_controller.end()) {
    return absl::NotFoundError(
        absl::StrCat("FanPidController with id ", controller_id, " not found"));
  }
  if (!fan_pid_controller_it->second->GetZoneManager()->GetTuningEnabled()) {
    return absl::InternalError(
        absl::StrCat("Tuning mode is not enabled for the controller ",
                     controller_id, "'s zone."));
  }

  auto zone_ids_it = controller_id_to_zone_ids_.find(controller_id);
  if (zone_ids_it == controller_id_to_zone_ids_.end()) {
    return absl::NotFoundError(absl::StrCat(
        "There is no zone associated with controller ", controller_id));
  }

  absl::MutexLock lock(tuning_mutex_);
  controller_id_to_pending_fan_pid_coefficient_[controller_id] = coefficients;
  for (int zone_id : zone_ids_it->second) {
    zone_ids_with_pending_tuning_request_.insert(zone_id);
  }
  return absl::OkStatus();
}

void ThermalCollector::ApplyPendingTuningRequests(int zone_id) {
  absl::MutexLock lock(tuning_mutex_);

  if (!zone_ids_with_pending_tuning_request_.contains(zone_id)) {
    return;
  }

  thermal::ZoneManager* zone_manager = zone_id_to_zone_manager_[zone_id].get();

  // Update coefficients for thermal controllers.
  for (const thermal::ThermalController* controller :
       zone_manager->GetAllThermalControllers()) {
    const std::string controller_id = controller->GetId();

    // Try to apply PID controller tuning requests.
    auto pid_controller_it = zone_id_and_controller_id_to_pid_controller_.find(
        std::make_tuple(zone_id, controller_id));
    if (pid_controller_it !=
        zone_id_and_controller_id_to_pid_controller_.end()) {
      auto pending_pid_coefficient_it =
          controller_id_to_pending_pid_coefficient_.find(controller_id);
      if (pending_pid_coefficient_it !=
          controller_id_to_pending_pid_coefficient_.end()) {
        pid_controller_it->second->SetCoefficients(
            pending_pid_coefficient_it->second);
      }
    }
  }

  // Update coefficients for fan controllers.
  for (const thermal::ThermalController* controller :
       zone_manager->GetAllFanControllers()) {
    const std::string controller_id = controller->GetId();

    // Try to apply fan PID controller tuning requests.
    auto fan_pid_controller_it =
        zone_id_and_controller_id_to_fan_pid_controller_.find(
            std::make_tuple(zone_id, controller_id));
    if (fan_pid_controller_it !=
        zone_id_and_controller_id_to_fan_pid_controller_.end()) {
      auto pending_fan_pid_coefficient_it =
          controller_id_to_pending_fan_pid_coefficient_.find(controller_id);
      if (pending_fan_pid_coefficient_it !=
          controller_id_to_pending_fan_pid_coefficient_.end()) {
        fan_pid_controller_it->second->SetCoefficients(
            pending_fan_pid_coefficient_it->second);
      }
    }
  }

  zone_ids_with_pending_tuning_request_.erase(zone_id);
}

bool ThermalCollector::HasPendingTuningRequest(
    absl::string_view controller_id) {
  auto zone_ids_it = controller_id_to_zone_ids_.find(controller_id);
  if (zone_ids_it == controller_id_to_zone_ids_.end()) {
    return false;
  }

  absl::MutexLock lock(tuning_mutex_);
  for (int zone_id : zone_ids_it->second) {
    if (zone_ids_with_pending_tuning_request_.contains(zone_id)) {
      return true;
    }
  }

  return false;
}

absl::StatusOr<thermal::PidOptimizerInfo> ThermalCollector::CreatePidAutoTuner(
    const PidControllerConfig& pid_controller_config) {
  // Create the auto-tuner.
  std::unique_ptr<thermal::optimizer::PidOptimizer> pid_optimizer = nullptr;
  if (pid_controller_config.pid_autotuner_config()
          .has_ziegler_nichols_config()) {
    ECCLESIA_ASSIGN_OR_RETURN(
        pid_optimizer, thermal::optimizer::PidAutotunerZieglerNichols::Create(
                           pid_controller_config));
  } else if (pid_controller_config.pid_autotuner_config()
                 .has_differentiated_ziegler_nichols_config()) {
    ECCLESIA_ASSIGN_OR_RETURN(
        pid_optimizer,
        thermal::optimizer::PidAutotunerDifferentiatedZieglerNichols::Create(
            pid_controller_config));
  } else if (pid_controller_config.pid_autotuner_config()
                 .has_frequency_response_estimation_config()) {
    ECCLESIA_ASSIGN_OR_RETURN(
        pid_optimizer,
        thermal::optimizer::PidAutotunerFrequencyResponseEstimation::Create(
            pid_controller_config));
  }

  if (pid_optimizer == nullptr) {
    return absl::InvalidArgumentError(
        "No valid PID auto-tuner config is found in the PID controller "
        "config.");
  }

  // Set up auto-tuner states.
  thermal::optimizer::PidOptimizerStates pid_optimizer_states;
  pid_optimizer_states.pid_optimizer_init_params = {
      .coeff_p = pid_controller_config.pid_loop_config().coeff_proportional(),
      .coeff_i = pid_controller_config.pid_loop_config().coeff_integral(),
      .coeff_d = pid_controller_config.pid_loop_config().coeff_derivative(),
  };

  return thermal::PidOptimizerInfo{
      .states = pid_optimizer_states,
      .optimizer = std::move(pid_optimizer),
  };
}

void ThermalCollector::ProcessOneThermalLoop(
    thermal::ZoneManager* zone_manager) {
  zone_manager->ClearSetpoints();
  zone_manager->UpdateAllSensorValues();
  zone_manager->ProcessThermalControllers();
  zone_manager->DetermineMaximumSetpoint();
}

void ThermalCollector::ProcessThermalControl(
    thermal::ZoneManager* zone_manager,
    const std::shared_ptr<boost::asio::steady_timer>& timer, bool first_run,
    uint64_t ms_elapsed_in_current_cycle) {
  if (stop_thermal_control_) {
    return;
  }

  std::chrono::steady_clock::time_point next_activation_time;
  if (first_run) {
    zone_manager->InitializeThermalStates();
    ProcessOneThermalLoop(zone_manager);
    next_activation_time = std::chrono::steady_clock::now();
    // Avoid dumping the first iteration data, which is for preparation of
    // successive runs.
    if (zone_manager->GetDebugEnabled()) {
      zone_manager->ClearSampledData();
    }
  } else {
    next_activation_time = timer->expiry();
  }

  uint64_t ms_per_fan_cycle = zone_manager->GetMsPerFanCycle();
  // Push forward the original expiration time of timer, instead of just
  // resetting it with expires_after() from now, to make sure the interval
  // is of the expected duration, and not stretched out by CPU time taken.
  next_activation_time += std::chrono::milliseconds(ms_per_fan_cycle);
  timer->expires_at(next_activation_time);

  timer->async_wait(
      [this, zone_manager, timer, ms_elapsed_in_current_cycle,
       ms_per_fan_cycle](const boost::system::error_code& ec) mutable {
        if (stop_thermal_control_.load(std::memory_order_relaxed) ||
            ec == boost::asio::error::operation_aborted ||
            ec == boost::system::errc::operation_canceled) {
          return;  // timer being canceled, stop loop
        }

        // Under tuning mode, try update coefficients first, if there is any
        // pending request.
        if (zone_manager->GetTuningEnabled()) {
          ApplyPendingTuningRequests(zone_manager->GetId());
        }

        // Under manual mode, simply trigger the next thermal control iteration,
        // and then return, without executing the thermal and fan cycles.
        if (zone_manager->GetManualMode()) {
          ProcessThermalControl(zone_manager, timer, /*first_run=*/false,
                                ms_elapsed_in_current_cycle);
          return;
        }

        uint64_t ms_per_thermal_cycle = zone_manager->GetMsPerThermalCycle();

        // Process thermal cycles no more frequently than fan cycles.
        // If the thermal interval is not an exact multiple of the fan interval,
        // there will be some remainder left over.
        bool process_thermal_cycle = false;
        if (ms_elapsed_in_current_cycle >= ms_per_thermal_cycle) {
          // Keep the timing correct, as the intervals are overlapping.
          ms_elapsed_in_current_cycle -= ms_per_thermal_cycle;
          ProcessOneThermalLoop(zone_manager);
          process_thermal_cycle = true;
        } else {
          // We need to update fan sensor values for fan controllers in EVERY
          // iteration. Alternatively, we may just update fan rpms here, instead
          // of all sensors, but this is hardly a performance improvement, and
          // will introduce more complexity.
          zone_manager->UpdateAllSensorValues();
        }

        // Process fan controllers and write fan speeds in every iteration.
        zone_manager->ProcessFanControllers();
        zone_manager->WriteFanSpeeds();

        if (zone_manager->GetDebugEnabled()) {
          // Clear the sampled data if only fan cycles are processed, to avoid
          // data misalignment.
          process_thermal_cycle ? zone_manager->DumpSampledData()
                                : zone_manager->ClearSampledData();
        }

        // Count how many milliseconds have elapsed to determine when to perform
        // thermal cycles, in a proper ratio with fan cycles.
        ms_elapsed_in_current_cycle += ms_per_fan_cycle;

        ProcessThermalControl(zone_manager, timer,
                              /*first_run=*/false, ms_elapsed_in_current_cycle);
      });
}

std::unique_ptr<EmptyThermalCollector> EmptyThermalCollector::Create() {
  return std::make_unique<EmptyThermalCollector>();
}

std::vector<const thermal::ZoneManager*>
EmptyThermalCollector::GetAllThermalZones() const {
  LOG(WARNING) << "EmptyThermalCollector::GetAllThermalZones is "
                  "called. This will return an empty list.";
  return {};
}

std::vector<const thermal::FirstOrderAdrcController*>
EmptyThermalCollector::GetAllFirstOrderAdrcControllers() const {
  LOG(WARNING) << "EmptyThermalCollector::GetAllFirstOrderAdrcControllers is "
                  "called. This will return an empty list.";
  return {};
}

std::vector<const thermal::SecondOrderAdrcController*>
EmptyThermalCollector::GetAllSecondOrderAdrcControllers() const {
  LOG(WARNING) << "EmptyThermalCollector::GetAllSecondOrderAdrcControllers is "
                  "called. This will return an empty list.";
  return {};
}

std::vector<const thermal::PidController*>
EmptyThermalCollector::GetAllPidControllers() const {
  LOG(WARNING) << "EmptyThermalCollector::GetAllPidControllers is "
                  "called. This will return an empty list.";
  return {};
}

std::vector<const thermal::StepwiseController*>
EmptyThermalCollector::GetAllStepwiseControllers() const {
  LOG(WARNING) << "EmptyThermalCollector::GetAllStepwiseControllers is "
                  "called. This will return an empty list.";
  return {};
}

std::vector<const thermal::DffController*>
EmptyThermalCollector::GetAllDffControllers() const {
  LOG(WARNING) << "EmptyThermalCollector::GetAllDffControllers is "
                  "called. This will return an empty list.";
  return {};
}

std::vector<const thermal::FanPidController*>
EmptyThermalCollector::GetAllFanPidControllers() const {
  LOG(WARNING) << "EmptyThermalCollector::GetAllFanPidControllers is "
                  "called. This will return an empty list.";
  return {};
}

std::vector<const thermal::EatController*>
EmptyThermalCollector::GetAllEatControllers() const {
  LOG(WARNING) << "EmptyThermalCollector::GetAllEatControllers is "
                  "called. This will return an empty list.";
  return {};
}

absl::StatusOr<const thermal::ZoneManager*>
EmptyThermalCollector::GetThermalZoneById(int zone_id) const {
  LOG(WARNING) << "EmptyThermalCollector::GetThermalZoneById is "
                  "called. This will return a nullptr.";
  return nullptr;
}

absl::StatusOr<const thermal::FirstOrderAdrcController*>
EmptyThermalCollector::GetFirstOrderAdrcControllerById(
    absl::string_view controller_id) const {
  LOG(WARNING) << "EmptyThermalCollector::GetFirstOrderAdrcControllerById is "
                  "called. This will return a nullptr.";
  return nullptr;
}

absl::StatusOr<const thermal::SecondOrderAdrcController*>
EmptyThermalCollector::GetSecondOrderAdrcControllerById(
    absl::string_view controller_id) const {
  LOG(WARNING) << "EmptyThermalCollector::GetSecondOrderAdrcControllerById is "
                  "called. This will return a nullptr.";
  return nullptr;
}

absl::StatusOr<const thermal::PidController*>
EmptyThermalCollector::GetPidControllerById(
    absl::string_view controller_id) const {
  LOG(WARNING) << "EmptyThermalCollector::GetPidControllerById is "
                  "called. This will return a nullptr.";
  return nullptr;
}

absl::StatusOr<const thermal::StepwiseController*>
EmptyThermalCollector::GetStepwiseControllerById(
    absl::string_view controller_id) const {
  LOG(WARNING) << "EmptyThermalCollector::GetStepwiseControllerById is "
                  "called. This will return a nullptr.";
  return nullptr;
}

absl::StatusOr<const thermal::DffController*>
EmptyThermalCollector::GetDffControllerById(
    absl::string_view controller_id) const {
  LOG(WARNING) << "EmptyThermalCollector::GetDffControllerById is "
                  "called. This will return a nullptr.";
  return nullptr;
}

absl::StatusOr<const thermal::EatController*>
EmptyThermalCollector::GetEatControllerById(
    absl::string_view controller_id) const {
  LOG(WARNING) << "EmptyThermalCollector::GetEatControllerById is "
                  "called. This will return a nullptr.";
  return nullptr;
}

absl::StatusOr<const thermal::FanPidController*>
EmptyThermalCollector::GetFanPidControllerById(
    absl::string_view controller_id) const {
  LOG(WARNING) << "EmptyThermalCollector::GetFanPidControllerById is "
                  "called. This will return a nullptr.";
  return nullptr;
}

nlohmann::json EmptyThermalCollector::GetSchedulerStats() const {
  return nlohmann::json::parse(
      "{\"Warning\": \"EmptyThermalCollector used.\"}");
}

nlohmann::json EmptyThermalCollector::ToJson() const {
  return nlohmann::json::parse(
      "{\"Warning\": \"EmptyThermalCollector used.\"}");
}

void EmptyThermalCollector::StartCollection() {
  LOG(WARNING) << "EmptyThermalCollector::StartCollection is "
                  "called. This does nothing.";
}

void EmptyThermalCollector::SetManualMode(bool enable) {
  LOG(WARNING) << "EmptyThermalCollector::SetManualMode is "
                  "called. This does nothing.";
}

absl::flat_hash_map<int, bool> EmptyThermalCollector::GetZoneIdToManualModes()
    const {
  LOG(WARNING) << "EmptyThermalCollector::GetZoneIdToManualModes is "
                  "called. This will return an empty map.";
  return {};
}

void EmptyThermalCollector::SetManualPwm(absl::string_view fan_name,
                                         double pwm) {
  LOG(WARNING) << "EmptyThermalCollector::SetManualPwm is "
                  "called. This does nothing.";
}

absl::Status EmptyThermalCollector::RequestPidControllerCoefficientsTuning(
    absl::string_view controller_id,
    const thermal::PidController::PidControllerCoefficients& coefficients) {
  LOG(WARNING)
      << "EmptyThermalCollector::RequestPidControllerCoefficientsTuning is "
         "called. This does nothing.";
  return absl::OkStatus();
}

absl::Status EmptyThermalCollector::RequestFanPidControllerCoefficientsTuning(
    absl::string_view controller_id,
    const thermal::FanPidController::FanPidControllerCoefficients&
        coefficients) {
  LOG(WARNING)
      << "EmptyThermalCollector::RequestFanPidControllerCoefficientsTuning is "
         "called. This does nothing.";
  return absl::OkStatus();
}

}  // namespace milotic_tlbmc
