#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 "i2c_common_config.pb.h"
#include "reading_range_config.pb.h"
#include "threshold_config.pb.h"
#include "tlbmc/hal/sysfs/i2c.h"
#include "resource.pb.h"
#include "sensor.pb.h"
#include "tlbmc/sensors/fan_controller.h"
#include "tlbmc/sensors/i2c_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 I2cSysfs& i2c_sysfs, std::optional<NotificationCb> on_batch_notify) {
  DLOG(INFO) << "Creating fan tach for device: " << absl::StrCat(config);
  const I2cCommonConfig& i2c_common_config = config.i2c_common_config();
  if (!fan_controller.ControllerHasSensor(i2c_common_config)) {
    return absl::InvalidArgumentError(
        absl::Substitute("Fan controller $0 does not have sensor $1",
                         absl::StrCat(fan_controller.GetI2cCommonConfig()),
                         absl::StrCat(i2c_common_config)));
  }

  auto it = fan_controller.GetIndexToTachs().find(config.index());
  if (it == fan_controller.GetIndexToTachs().end()) {
    if (!GetTlbmcConfig().allow_sensor_creation_failure) {
      return absl::InvalidArgumentError(absl::Substitute(
          "Fan controller $0 does not have a tach file at index $1",
          absl::StrCat(fan_controller.GetI2cCommonConfig()), 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.GetI2cCommonConfig()),
                      config.index());
    std::shared_ptr<FanTachometer> fan_tach = std::make_shared<FanTachometer>(
        Token(), config.type(), "", absl::StrCat("fantach_", config.name()),
        config.i2c_common_config(), config.thresholds(),
        config.reading_ranges(), config.entity_common_config(), io_context,
        on_batch_notify);
    State state;
    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.i2c_common_config(), config.thresholds(), config.reading_ranges(),
      config.entity_common_config(), io_context, on_batch_notify);
}

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;
  uint64_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 I2cCommonConfig& i2c_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)
    : I2cHwmonBasedSensor(
          input_dev_path, io_context,
          CreateStaticAttributes(sensor_name, UNIT_REVOLUTION_PER_MINUTE,
                                 i2c_common_config, entity_common_config,
                                 threshold_configs, reading_range_configs),
          on_batch_notify),
      sensor_type_(sensor_type),
      sensor_name_(sensor_name),
      board_config_name_(entity_common_config.board_config_name()) {}

}  // namespace milotic_tlbmc
