#include "tlbmc/sensors/fan_pwm.h"

#include <array>
#include <charconv>
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <ios>
#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
#include "g3/macros.h"
// 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_pwm_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::Status FanPwm::EnablePwm(const boost::filesystem::path& pwm_enable_path) {
  std::fstream file_in(pwm_enable_path.string(), std::ios::in);
  if (!file_in.good()) {
    return absl::InternalError(
        absl::StrCat("Error open ", pwm_enable_path.string()));
  }
  std::string mode;
  std::getline(file_in, mode);
  if (mode == "0") {
    DLOG(INFO) << "Enabling fan PWM for " << pwm_enable_path.string();
    std::ofstream file_out(pwm_enable_path.string(), std::ios::out);
    file_out.clear();
    file_out.seekp(0, std::ios::beg);
    file_out << 1;
    file_out.flush();
  }
  return absl::OkStatus();
}

absl::StatusOr<std::shared_ptr<Sensor>> FanPwm::Create(
    const FanPwmConfig& 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 PWM 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.GetIndexToPwms().find(config.index());
  if (it == fan_controller.GetIndexToPwms().end()) {
    if (!GetTlbmcConfig()
             .sensor_collector_module()
             .allow_sensor_creation_failure()) {
      return absl::InvalidArgumentError(absl::Substitute(
          "Fan controller $0 does not have a PWM file at index $1",
          absl::StrCat(fan_controller.GetI2cCommonConfig()), config.index()));
    }
    LOG(ERROR) << "Failed to create FanPwm (NONFATAL): "
               << absl::Substitute(
                      "Fan controller $0 does not have a PWM file at index $1",
                      absl::StrCat(fan_controller.GetI2cCommonConfig()),
                      config.index());
    std::shared_ptr<FanPwm> fan_pwm = std::make_shared<FanPwm>(
        Token(), config.type(), "", absl::StrCat("fanpwm_", 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 FanPwm Sensor (NONFATAL)");
    fan_pwm->UpdateState(std::move(state));
    return fan_pwm;
  }
  // Enable PWM
  ECCLESIA_RETURN_IF_ERROR(EnablePwm(it->second.pwm_enable));

  std::string fan_pwm_key = absl::StrCat("fanpwm_", config.name());

  return std::make_shared<FanPwm>(
      Token(), config.type(), it->second.pwm.string(), fan_pwm_key,
      config.i2c_common_config(), config.thresholds(), config.reading_ranges(),
      config.entity_common_config(), io_context, on_batch_notify);
}

void FanPwm::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.mutable_timestamp() = Now();
  sensor_data.set_reading(((static_cast<double>(value) / 255) * scale_));
  StoreSensorData(std::make_shared<const SensorValue>(std::move(sensor_data)));
  State state;
  state.set_status(STATUS_READY);
  UpdateState(std::move(state));
}

FanPwm::FanPwm(Token token, FanPwmType 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_PERCENT, 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
