#include "tlbmc/sensors/fan_tach.h"

#include <array>
#include <charconv>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <system_error>  // NOLINT: system_error is commonly used in BMC
#include <utility>

#include "google/protobuf/duration.pb.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/substitute.h"
#include "boost/asio.hpp"  // NOLINT: boost::asio is commonly used in BMC
#include "boost/asio/random_access_file.hpp"  // NOLINT: boost::asio is commonly used in BMC
#include "boost/filesystem.hpp"  // NOLINT: boost::filesystem is commonly used in BMC
#include "boost/filesystem/operations.hpp"  // NOLINT: boost::filesystem is commonly used in BMC
#include "boost/system/detail/error_code.hpp"  // NOLINT: boost::asio is commonly used in BMC
// NOLINTNEXTLINE: keep this so BUILD file will keep liburing
#include "liburing.h"  // IWYU pragma: keep
#include "tlbmc/central_config/config.h"
#include "entity_common_config.pb.h"
#include "fan_tach_config.pb.h"
#include "hal_common_config.pb.h"
#include "reading_range_config.pb.h"
#include "threshold_config.pb.h"
#include "tlbmc/hal/sysfs/hwmon.h"
#include "resource.pb.h"
#include "sensor.pb.h"
#include "tlbmc/sensors/fan_controller.h"
#include "tlbmc/sensors/ixc_hwmon_based_sensor.h"
#include "tlbmc/sensors/sensor.h"
#include "tlbmc/time/time.h"

namespace milotic_tlbmc {

absl::StatusOr<std::shared_ptr<Sensor>> FanTachometer::Create(
    const FanTachConfig& config, const FanController& fan_controller,
    const std::shared_ptr<boost::asio::io_context>& io_context,
    const HwmonSysfs& hwmon_sysfs,
    std::optional<NotificationCb> on_batch_notify) {
  DLOG(INFO) << "Creating fan tach for device: " << absl::StrCat(config);
  const HalCommonConfig& hal_common_config = config.hal_common_config();
  if (!fan_controller.ControllerHasSensor(hal_common_config)) {
    return absl::InvalidArgumentError(
        absl::Substitute("Fan controller $0 does not have sensor $1",
                         absl::StrCat(fan_controller.GetHalCommonConfig()),
                         absl::StrCat(hal_common_config)));
  }

  auto it = fan_controller.GetIndexToTachs().find(config.index());
  if (it == fan_controller.GetIndexToTachs().end()) {
    // Only fail if the sensor is detected and the config is not allowed to
    // fail.
    if (!GetTlbmcConfig()
             .sensor_collector_module()
             .allow_sensor_creation_failure() &&
        config.entity_common_config().config_detected()) {
      return absl::InvalidArgumentError(absl::Substitute(
          "Fan controller $0 does not have a tach file at index $1",
          absl::StrCat(fan_controller.GetHalCommonConfig()), config.index()));
    }
    LOG(ERROR) << "Failed to create FanTachometer (NONFATAL): "
               << absl::Substitute(
                      "Fan controller $0 does not have a tach file at index $1",
                      absl::StrCat(fan_controller.GetHalCommonConfig()),
                      config.index());
    std::shared_ptr<FanTachometer> fan_tach = std::make_shared<FanTachometer>(
        Token(), config.type(), "", absl::StrCat("fantach_", config.name()),
        config.hal_common_config(), config.thresholds(),
        config.reading_ranges(), config.entity_common_config(), io_context,
        on_batch_notify, hwmon_sysfs);
    State state;
    // If the sensor is not detected, we set its creation as pending otherwise
    // set it to failed.
    if (!config.entity_common_config().config_detected()) {
      state.set_status(STATUS_CREATION_PENDING);
    } else {
      state.set_status(STATUS_CREATION_FAILED);
    }
    state.set_status_message("Failed to create FanTach Sensor (NONFATAL)");
    fan_tach->UpdateState(std::move(state));
    return fan_tach;
  }

  std::string fan_tach_key = absl::StrCat("fantach_", config.name());

  return std::make_shared<FanTachometer>(
      Token(), config.type(), it->second.tach_input.string(), fan_tach_key,
      config.hal_common_config(), config.thresholds(), config.reading_ranges(),
      config.entity_common_config(), io_context, on_batch_notify, hwmon_sysfs);
}

void FanTachometer::HandleRefreshResult(const boost::system::error_code& error,
                                        size_t bytes_read) {
  if (error) {
    State state;
    state.set_status(STATUS_STALE);
    state.set_status_message(absl::Substitute(
        "Failed to read from input device: $0; input device path: $1",
        error.message(), GetInputDevicePath()));
    UpdateState(std::move(state));
    return;
  }
  const char* buffer_end = GetConstReadBuffer().data() + bytes_read;
  int64_t value = 0;
  std::from_chars_result result =
      std::from_chars(GetConstReadBuffer().data(), buffer_end, value);
  if (result.ec != std::errc()) {
    State state;
    state.set_status(STATUS_STALE);
    state.set_status_message(
        absl::StrCat("Read data can't be converted to a number: ",
                     std::make_error_condition(result.ec).message()));
    UpdateState(std::move(state));
    return;
  }
  SensorValue sensor_data;
  sensor_data.set_reading(static_cast<double>(value));
  *sensor_data.mutable_timestamp() = Now();
  StoreSensorData(std::make_shared<const SensorValue>(std::move(sensor_data)));
  State state;
  state.set_status(STATUS_READY);
  UpdateState(std::move(state));
}

FanTachometer::FanTachometer(
    Token token, FanTachType sensor_type, const std::string& input_dev_path,
    const std::string& sensor_name, const HalCommonConfig& hal_common_config,
    const ThresholdConfigs& threshold_configs,
    const ReadingRangeConfigs& reading_range_configs,
    const EntityCommonConfig& entity_common_config,
    const std::shared_ptr<boost::asio::io_context>& io_context,
    std::optional<NotificationCb> on_batch_notify,
    const HwmonSysfs& hwmon_sysfs)
    : IXcHwmonBasedSensor(
          input_dev_path, io_context,
          CreateStaticAttributes(sensor_name, UNIT_REVOLUTION_PER_MINUTE,
                                 hal_common_config, entity_common_config,
                                 reading_range_configs,
                                 /*reading_transform_config=*/{}),
          threshold_configs, on_batch_notify, hwmon_sysfs),
      sensor_type_(sensor_type),
      sensor_name_(sensor_name) {}

}  // namespace milotic_tlbmc
