#include "tlbmc/sensors/hwmon_temp_sensor.h"

#include <algorithm>
#include <array>
#include <charconv>
#include <cstddef>
#include <cstdint>
#include <fstream>
#include <iterator>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <system_error>  // NOLINT: system_error is commonly used in BMC
#include <unordered_map>
#include <utility>
#include <vector>

#include "google/protobuf/duration.pb.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/ascii.h"
#include "absl/strings/match.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 "hwmon_temp_sensor_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/i2c_hwmon_based_sensor.h"
#include "tlbmc/sensors/sensor.h"
#include "tlbmc/time/time.h"

namespace milotic_tlbmc {

template <class TypeName>
struct TypeComparator {
  // Compared by the first element which is the type name.
  bool operator()(const std::pair<HwmonTempSensorType, TypeName>& lhs,
                  const std::pair<HwmonTempSensorType, TypeName>& rhs) const {
    return lhs.first < rhs.first;
  }
};

constexpr std::array<std::pair<HwmonTempSensorType, std::string_view>, 3>
    kSupportedHwmonTempSensorTypes = {
        // go/keep-sorted start numeric=yes
        {{HWMON_TEMP_SENSOR_TYPE1_MAX31725, "max31725"},
         {HWMON_TEMP_SENSOR_TYPE2_TMP75, "tmp75"},
         {HWMON_TEMP_SENSOR_TYPE3_MAX31732, "max31732"}}
        // go/keep-sorted end
};

absl::StatusOr<std::string_view> HwmonTempSensor::GetDriverName(
    HwmonTempSensorType sensor_type) {
  const auto* it = std::lower_bound(
      kSupportedHwmonTempSensorTypes.begin(),
      kSupportedHwmonTempSensorTypes.end(),
      std::pair<HwmonTempSensorType, std::string_view>{sensor_type, ""},
      TypeComparator<std::string_view>());
  if (it == kSupportedHwmonTempSensorTypes.end() || it->first != sensor_type) {
    return absl::InvalidArgumentError(
        absl::Substitute("Unsupported sensor type: $0", sensor_type));
  }
  return it->second;
}

absl::StatusOr<std::vector<std::shared_ptr<Sensor>>> HwmonTempSensor::Create(
    const HwmonTempSensorConfig& config,
    const std::shared_ptr<boost::asio::io_context>& io_context,
    const I2cSysfs& i2c_sysfs, std::optional<NotificationCb> on_batch_notify) {
  DLOG(INFO) << "Creating HwmonTempSensor for device: " << absl::StrCat(config);

  const I2cCommonConfig& i2c_common_config = config.i2c_common_config();
  ECCLESIA_ASSIGN_OR_RETURN(std::string_view driver_name,
                            GetDriverName(config.type()));

  std::vector<std::shared_ptr<Sensor>> sensors;

  absl::StatusOr<boost::filesystem::path> hwmon_path =
      I2cHwmonBasedSensor::CreateDeviceAndReturnsHwmonPath(
          i2c_common_config, driver_name, i2c_sysfs);
  if (!hwmon_path.ok()) {
    if (!GetTlbmcConfig().allow_sensor_creation_failure) {
      return hwmon_path.status();
    }

    LOG(ERROR) << "Failed to create HwmonTempSensor (NONFATAL): "
               << hwmon_path.status();
    for (const auto& [label, name] : config.label_to_name()) {
      std::string hwmon_temp_sensor_key = absl::StrCat("temperature_", name);
      std::shared_ptr<HwmonTempSensor> hwmon_temp_sensor =
          std::make_shared<HwmonTempSensor>(
              Token(), config.type(), "", hwmon_temp_sensor_key,
              config.i2c_common_config(), ThresholdConfigs(),
              ReadingRangeConfigs(), config.entity_common_config(), io_context,
              on_batch_notify);
      State state;
      state.set_status(STATUS_CREATION_FAILED);
      state.set_status_message(
          absl::StrCat("Failed to create HwmonTempSensor (NONFATAL): ",
                       hwmon_path.status()));
      hwmon_temp_sensor->UpdateState(std::move(state));
      sensors.push_back(hwmon_temp_sensor);
    }
    return sensors;
  }

  // Now find all labels and their input files.
  std::unordered_map<std::string, std::string> label_to_input_file;
  for (const auto& entry : boost::filesystem::directory_iterator(*hwmon_path)) {
    constexpr std::string_view kInputFileSuffix = "_input";
    constexpr std::string_view kLabelSuffix = "_label";
    if (entry.is_regular_file() &&
        absl::EndsWith(entry.path().filename().string(), kInputFileSuffix)) {
      // e.g., /sys/bus/i2c/devices/i2c-21/21-0040/hwmon/hwmon15/temp100_input
      std::string input_file = entry.path().filename().string();
      std::string file_prefix =
          input_file.substr(0, input_file.size() - kInputFileSuffix.size());
      std::string label_file = absl::StrCat(file_prefix, kLabelSuffix);
      // Both input file and label file should exist
      boost::filesystem::path label_path = *hwmon_path / label_file;
      if (boost::filesystem::exists(label_path)) {
        std::ifstream file(label_path.string());
        std::string label = {std::istreambuf_iterator<char>(file),
                             std::istreambuf_iterator<char>()};
        label = std::string(absl::StripTrailingAsciiWhitespace(label));
        label_to_input_file[label] = input_file;
      } else if (boost::filesystem::exists(*hwmon_path / input_file)) {
        // If label file does not exist, use input file name prefix as label.
        label_to_input_file[file_prefix] = input_file;
      }
    }
  }

  for (const auto& [label, name] : config.label_to_name()) {
    boost::filesystem::path input_dev_path;

    if (auto it = label_to_input_file.find(label);
        it != label_to_input_file.end()) {
      input_dev_path = *hwmon_path / it->second;
    } else {
      return absl::InvalidArgumentError(absl::Substitute(
          "Failed to find $0 in hwmon folder $1", label, hwmon_path->string()));
    }

    ThresholdConfigs threshold_configs;
    if (auto it = config.label_to_thresholds().find(label);
        it != config.label_to_thresholds().end()) {
      threshold_configs = it->second;
    }

    ReadingRangeConfigs reading_range_configs;
    if (auto it = config.label_to_reading_ranges().find(label);
        it != config.label_to_reading_ranges().end()) {
      reading_range_configs = it->second;
    }

    std::string hwmon_temp_sensor_key = absl::StrCat("temperature_", name);

    sensors.push_back(std::make_shared<HwmonTempSensor>(
        Token(), config.type(), input_dev_path.string(), hwmon_temp_sensor_key,
        config.i2c_common_config(), threshold_configs, reading_range_configs,
        config.entity_common_config(), io_context, on_batch_notify));
  }

  return sensors;
}

void HwmonTempSensor::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;
  }
  double scale = scale_;
  if (GetSensorAttributesStatic().unit() == UNIT_DEGREE_CELSIUS) {
    // Temperatures are read in milli degrees Celsius, we need
    // degrees Celsius.
    // https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
    scale *= 0.001;
  }
  SensorValue sensor_data;
  *sensor_data.mutable_timestamp() = Now();
  sensor_data.set_reading(((static_cast<double>(value) + offset_) * scale));
  StoreSensorData(std::make_shared<const SensorValue>(std::move(sensor_data)));
  State state;
  state.set_status(STATUS_READY);
  UpdateState(std::move(state));
}

HwmonTempSensor::HwmonTempSensor(
    Token token, HwmonTempSensorType 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_DEGREE_CELSIUS,
                                 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
