#include "tlbmc/sensors/psu_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 "i2c_common_config.pb.h"
#include "psu_sensor_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 TypeNameFirst, class TypeNameSecond>
struct TypeComparator {
  // Compared by the first element which is the type name.
  bool operator()(const std::pair<TypeNameFirst, TypeNameSecond>& lhs,
                  const std::pair<TypeNameFirst, TypeNameSecond>& rhs) const {
    return lhs.first < rhs.first;
  }
};

constexpr std::array<std::pair<PsuSensorType, std::string_view>, 12>
    kSupportedPsuSensorTypes = {
        // go/keep-sorted start numeric=yes
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE1_ADM1266, "adm1266"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE2_ADM1272, "adm1272"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE3_PMBUS, "pmbus"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE4_LTC2991, "ltc2991"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE5_RAA228228, "raa228228"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE6_TDA38725, "tda38725"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE7_TDA38740, "tda38740"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE8_XDPE1A2G5B, "xdpe1a2g5b"},
        // LTC4287 uses ltc4286 driver.
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE9_LTC4287, "ltc4286"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE10_Q50SN12072, "pmbus"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE11_Q54SN120A4, "pmbus"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE12_TPS25990, "tps25990"},
        // go/keep-sorted end
};

// Refer to https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface and
// see OpenBMC definition of PSU Sensor Properties:
// https://github.com/openbmc/dbus-sensors/blob/af1724b84b7558037c665d2106ec44d7362aca6b/src/psu/PSUSensorMain.cpp#L1095
constexpr std::array<std::pair<std::string_view, PsuSensor::ReadingProperties>,
                     9>
    kDefaultPsuSensorProperties = {
        // go/keep-sorted start
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "highestpin",  // input power
            PsuSensor::ReadingProperties{.label_type_name = "Peak Input Power",
                                         .max_reading = 3000.0,
                                         .min_reading = 0.0,
                                         .scale = 0.000001,
                                         .offset = 0.0,
                                         .sensor_unit = SensorUnit::UNIT_WATT}},
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "iin",  // input current
            PsuSensor::ReadingProperties{
                .label_type_name = "Input Current",
                .max_reading = 20.0,
                .min_reading = 0.0,
                .scale = 0.001,
                .offset = 0.0,
                .sensor_unit = SensorUnit::UNIT_AMPERE}},
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "iout",  // output current
            PsuSensor::ReadingProperties{
                .label_type_name = "Output Current",
                .max_reading = 255.0,
                .min_reading = 0.0,
                .scale = 0.001,
                .offset = 0.0,
                .sensor_unit = SensorUnit::UNIT_AMPERE}},
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "pin",  // input power
            PsuSensor::ReadingProperties{.label_type_name = "Input Power",
                                         .max_reading = 3000.0,
                                         .min_reading = 0.0,
                                         .scale = 0.000001,
                                         .offset = 0.0,
                                         .sensor_unit = SensorUnit::UNIT_WATT}},
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "pout",  // output power
            PsuSensor::ReadingProperties{.label_type_name = "Output Power",
                                         .max_reading = 3000.0,
                                         .min_reading = 0.0,
                                         .scale = 0.000001,
                                         .offset = 0.0,
                                         .sensor_unit = SensorUnit::UNIT_WATT}},
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "temp",  // temperature
            PsuSensor::ReadingProperties{
                .label_type_name = "Temperature",
                .max_reading = 127.0,
                .min_reading = -128.0,
                .scale = 0.001,
                .offset = 0.0,
                .sensor_unit = SensorUnit::UNIT_DEGREE_CELSIUS}},
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "vin",  // input voltage
            PsuSensor::ReadingProperties{.label_type_name = "Input Voltage",
                                         .max_reading = 300.0,
                                         .min_reading = 0.0,
                                         .scale = 0.001,
                                         .offset = 0.0,
                                         .sensor_unit = SensorUnit::UNIT_VOLT}},
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "voltage",  // output voltage
            PsuSensor::ReadingProperties{.label_type_name = "Output Voltage",
                                         .max_reading = 255.0,
                                         .min_reading = 0.0,
                                         .scale = 0.001,
                                         .offset = 0.0,
                                         .sensor_unit = SensorUnit::UNIT_VOLT}},
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "vout",  // output voltage
            PsuSensor::ReadingProperties{.label_type_name = "Output Voltage",
                                         .max_reading = 255.0,
                                         .min_reading = 0.0,
                                         .scale = 0.001,
                                         .offset = 0.0,
                                         .sensor_unit = SensorUnit::UNIT_VOLT}}
        // go/keep-sorted end
};

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

std::string PsuSensor::GetPsuSensorKey(
    std::string_view name, const PsuSensorConfig& config,
    PsuSensor::ReadingProperties properties) {
  std::string key = std::string(name);
  if (name.empty()) {
    // If sensor label name is not customized in the config, create key from
    // prefix of sensor Name field and suffix of label_type_name
    // https://github.com/openbmc/dbus-sensors/blob/556e04b8f374a9eb8cf32bf0e36ac46c14873eba/src/psu/PSUSensorMain.cpp#L934
    key = absl::StrCat(config.name(), "_", properties.label_type_name);
    std::replace(key.begin(), key.end(), ' ', '_');
  }
  switch (properties.sensor_unit) {
    case SensorUnit::UNIT_AMPERE:
      key = absl::StrCat("current_", key);
      break;
    case SensorUnit::UNIT_VOLT:
      key = absl::StrCat("voltage_", key);
      break;
    case SensorUnit::UNIT_WATT:
      key = absl::StrCat("power_", key);
      break;
    case SensorUnit::UNIT_DEGREE_CELSIUS:
      key = absl::StrCat("temperature_", key);
      break;
    default:
      // PSUSensors will never have these units
      LOG(WARNING) << "PsuSensor " << key
                   << " has unexpected unit: " << properties.sensor_unit;
      break;
  }
  return key;
}

absl::StatusOr<PsuSensor::ReadingProperties> PsuSensor::GetPsuSensorProperties(
    std::string_view label) {
  std::string_view label_no_digit = label;
  std::size_t first_index = label_no_digit.find_first_of("0123456789");
  if (first_index != std::string_view::npos) {
    label_no_digit = label_no_digit.substr(0, first_index);
  }
  const auto* it = std::lower_bound(
      kDefaultPsuSensorProperties.begin(), kDefaultPsuSensorProperties.end(),
      std::pair<std::string_view, PsuSensor::ReadingProperties>{
          label_no_digit, PsuSensor::ReadingProperties{}},
      TypeComparator<std::string_view, PsuSensor::ReadingProperties>());
  if (it == kDefaultPsuSensorProperties.end() || it->first != label_no_digit) {
    return absl::InvalidArgumentError(
        absl::Substitute("Unsupported sensor label: $0", label_no_digit));
  }
  return it->second;
}

absl::StatusOr<ReadingRangeConfigs> PsuSensor::GetReadingRangeConfigs(
    const ReadingRangeConfigs& configs, const ReadingProperties& properties) {
  ReadingRangeConfigs reading_range_configs = configs;
  bool has_max_reading_range = false;
  bool has_min_reading_range = false;
  for (const auto& reading_range_config :
       reading_range_configs.reading_range_configs()) {
    if (reading_range_config.type() == READING_RANGE_TYPE_MAX) {
      has_max_reading_range = true;
    } else if (reading_range_config.type() == READING_RANGE_TYPE_MIN) {
      has_min_reading_range = true;
    }
  }
  // Add the default reading ranges if they are not specified in the config.
  if (!has_max_reading_range) {
    ReadingRangeConfig* reading_range =
        reading_range_configs.add_reading_range_configs();
    reading_range->set_type(READING_RANGE_TYPE_MAX);
    reading_range->set_reading(properties.max_reading);
  }
  if (!has_min_reading_range) {
    ReadingRangeConfig* reading_range =
        reading_range_configs.add_reading_range_configs();
    reading_range->set_type(READING_RANGE_TYPE_MIN);
    reading_range->set_reading(properties.min_reading);
  }
  return reading_range_configs;
}

PsuSensorFileInfo PsuSensor::GetPsuSensorFileInfo(std::string_view input_file) {
  for (int i = 0; i < kPsuSensorFileSuffixes.size(); ++i) {
    std::string_view suffix = kPsuSensorFileSuffixes[i];
    if (absl::EndsWith(input_file, suffix)) {
      return {.file_prefix = std::string(
                  input_file.substr(0, input_file.size() - suffix.size())),
              .file_type = static_cast<PsuSensorFileType>(i)};
    }
  }
  return {.file_type = PsuSensorFileType::kUnknown};
}

absl::StatusOr<std::string> PsuSensor::ParseLabelFile(
    const boost::filesystem::path& hwmon_path, std::string_view file_prefix) {
  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(hwmon_path / label_file)) {
    return absl::InvalidArgumentError(
        absl::Substitute("Failed to find label file $0", label_file));
  }
  std::ifstream file(label_path.string());
  std::string label = {std::istreambuf_iterator<char>(file),
                       std::istreambuf_iterator<char>()};
  return std::string(absl::StripTrailingAsciiWhitespace(label));
}

std::string PsuSensor::ApplyLabelModifications(std::string_view label,
                                               PsuSensorFileType file_type) {
  // For unknown file type, just return the label.
  if (file_type == PsuSensorFileType::kUnknown) {
    return std::string(label);
  }
  return absl::StrCat(kPsuSensorLabelPrefixes[static_cast<int>(file_type)],
                      label);
}

std::string PsuSensor::GetLabel(const boost::filesystem::path& hwmon_path,
                                std::string_view file_prefix,
                                PsuSensorFileType file_type) {
  // Try to find a label file and use its contents as the label.
  // E.g. if the file prefix is "power1", then the label file should be at
  // "power1_label".
  // If the label file exists, then use the contents of the
  // label file as the label.
  // Otherwise, use the file_prefix as the label base.
  absl::StatusOr<std::string> label = ParseLabelFile(hwmon_path, file_prefix);
  if (!label.ok()) {
    return ApplyLabelModifications(file_prefix, file_type);
  }
  return ApplyLabelModifications(*label, file_type);
}

absl::StatusOr<std::vector<std::shared_ptr<Sensor>>> PsuSensor::Create(
    const PsuSensorConfig& config,
    const std::shared_ptr<boost::asio::io_context>& io_context,
    const I2cSysfs& i2c_sysfs, std::optional<NotificationCb> on_batch_notify) {
  DLOG(INFO) << "Creating PsuSensor 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;

  // E.g., /sys/bus/i2c/devices/20-0040/hwmon/hwmon18/
  absl::StatusOr<boost::filesystem::path> hwmon_path =
      I2cHwmonBasedSensor::CreateDeviceAndReturnsHwmonPath(
          i2c_common_config, driver_name, i2c_sysfs);
  if (!hwmon_path.ok()) {
    if (!GetTlbmcConfig()
             .sensor_collector_module()
             .allow_sensor_creation_failure()) {
      return hwmon_path.status();
    }

    LOG(ERROR) << "Failed to create PsuSensor (NONFATAL): "
               << hwmon_path.status();
    for (const auto& [label, name] : config.label_to_name()) {
      ECCLESIA_ASSIGN_OR_RETURN(PsuSensor::ReadingProperties properties,
                                GetPsuSensorProperties(label));
      std::string sensor_key = GetPsuSensorKey(name, config, properties);
      std::shared_ptr<PsuSensor> psu_sensor = std::make_shared<PsuSensor>(
          Token(), config.type(), properties.sensor_unit, "", sensor_key,
          config.i2c_common_config(), ThresholdConfigs(), ReadingRangeConfigs(),
          config.entity_common_config(), properties.scale, properties.offset,
          io_context, on_batch_notify);
      State state;
      state.set_status(STATUS_CREATION_FAILED);
      state.set_status_message(absl::StrCat(
          "Failed to create PsuSensor (NONFATAL): ", hwmon_path.status()));
      psu_sensor->UpdateState(std::move(state));
      sensors.push_back(psu_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)) {
    if (entry.is_regular_file()) {
      std::string input_file = entry.path().filename().string();
      PsuSensorFileInfo file_info = GetPsuSensorFileInfo(input_file);

      // Ignore sensors that we don't support
      if (file_info.file_type == PsuSensorFileType::kUnknown) {
        continue;
      }

      std::string label =
          GetLabel(*hwmon_path, file_info.file_prefix, file_info.file_type);
      label_to_input_file[label] = input_file;
    }
  }

  for (const auto& [label, name] : config.label_to_name()) {
    auto label_to_input_file_it = label_to_input_file.find(label);
    if (label_to_input_file_it == label_to_input_file.end()) {
      return absl::InvalidArgumentError(absl::Substitute(
          "Failed to find $0 in hwmon folder $1", label, hwmon_path->string()));
    }
    const std::string& input_file = label_to_input_file_it->second;
    boost::filesystem::path input_dev_path = *hwmon_path / input_file;

    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;
    }

    ECCLESIA_ASSIGN_OR_RETURN(PsuSensor::ReadingProperties properties,
                              GetPsuSensorProperties(label));
    ECCLESIA_ASSIGN_OR_RETURN(
        reading_range_configs,
        GetReadingRangeConfigs(reading_range_configs, properties));

    std::string sensor_key = GetPsuSensorKey(name, config, properties);

    sensors.push_back(std::make_shared<PsuSensor>(
        Token(), config.type(), properties.sensor_unit, input_dev_path.string(),
        sensor_key, config.i2c_common_config(), threshold_configs,
        reading_range_configs, config.entity_common_config(), properties.scale,
        properties.offset, io_context, on_batch_notify));
  }

  return sensors;
}

void PsuSensor::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) + offset_) * scale_);
  StoreSensorData(std::make_shared<const SensorValue>(std::move(sensor_data)));
  State state;
  state.set_status(STATUS_READY);
  UpdateState(std::move(state));
}

PsuSensor::PsuSensor(Token token, PsuSensorType sensor_type,
                     SensorUnit sensor_unit, 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,
                     double scale, double offset,
                     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, sensor_unit, 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()),
      scale_(scale),
      offset_(offset) {}

}  // namespace milotic_tlbmc
