#include "tlbmc/sensors/psu_sensor.h"

#include <algorithm>
#include <array>
#include <charconv>
#include <cmath>
#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 <utility>
#include <vector>

#include "google/protobuf/duration.pb.h"
#include "absl/container/flat_hash_map.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 "hal_common_config.pb.h"
#include "psu_sensor_config.pb.h"
#include "reading_range_config.pb.h"
#include "reading_transform_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/ixc_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>, 16>
    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"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE13_RAA229639, "isl68137"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE14_LX6301, "pmbus"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE15_SBTSI_I3C, "sbtsi_i3c"},
        std::pair<PsuSensorType, std::string_view>{
            PsuSensorType::PSU_SENSOR_TYPE16_TPS546E25, "pmbus"},
        // go/keep-sorted end
};

constexpr std::array<PsuSensorType, 1> kSupportedI3cPsuSensorTypes = {
    // go/keep-sorted start numeric=yes
    PsuSensorType::PSU_SENSOR_TYPE15_SBTSI_I3C,
    // 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>,
                     13>
    kDefaultPsuSensorProperties = {
        // go/keep-sorted start
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "highestiout",  // output current
            PsuSensor::ReadingProperties{
                .label_type_name = "Peak Output Current",
                .max_reading = 255.0,
                .min_reading = 0.0,
                .scale = 3,
                .offset = 0.0,
                .sensor_unit = SensorUnit::UNIT_AMPERE}},
        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 = 6,
                                         .offset = 0.0,
                                         .sensor_unit = SensorUnit::UNIT_WATT}},
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "highesttemp",  // peak temperature
            PsuSensor::ReadingProperties{
                .label_type_name = "Peak Temperature",
                .max_reading = 127.0,
                .min_reading = -128.0,
                .scale = 3,
                .offset = 0.0,
                .sensor_unit = SensorUnit::UNIT_DEGREE_CELSIUS}},
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "highestvin",  // input voltage
            PsuSensor::ReadingProperties{
                .label_type_name = "Peak Input Voltage",
                .max_reading = 300.0,
                .min_reading = 0.0,
                .scale = 3,
                .offset = 0.0,
                .sensor_unit = SensorUnit::UNIT_VOLT}},
        std::pair<std::string_view, PsuSensor::ReadingProperties>{
            "highestvout",  // output voltage
            PsuSensor::ReadingProperties{
                .label_type_name = "Peak Output Voltage",
                .max_reading = 255.0,
                .min_reading = 0.0,
                .scale = 3,
                .offset = 0.0,
                .sensor_unit = SensorUnit::UNIT_VOLT}},
        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 = 3,
                .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 = 3,
                .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 = 6,
                                         .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 = 6,
                                         .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 = 3,
                .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 = 3,
                                         .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 = 3,
                                         .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 = 3,
                                         .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 HwmonSysfs& hwmon_sysfs,
    std::optional<NotificationCb> on_batch_notify) {
  DLOG(INFO) << "Creating PsuSensor for device: " << absl::StrCat(config);
  const HalCommonConfig& hal_common_config = config.hal_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;
  hwmon_path = IXcHwmonBasedSensor::CreateIXcDeviceAndReturnsHwmonPath(
      hal_common_config, driver_name, hwmon_sysfs);
  if (!hwmon_path.ok()) {
    // 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 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.hal_common_config(), ThresholdConfigs(), ReadingRangeConfigs(),
          ReadingTransformConfig(), 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(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.
  absl::flat_hash_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));

    ReadingTransformConfig reading_transform_config;
    if (auto it = config.label_to_reading_transform().find(label);
        it != config.label_to_reading_transform().end()) {
      reading_transform_config = it->second;
    }

    if (!reading_transform_config.has_scale()) {
      reading_transform_config.set_scale(std::pow(10, properties.scale));
    }
    if (!reading_transform_config.has_offset()) {
      reading_transform_config.set_offset(properties.offset);
    }

    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.hal_common_config(), threshold_configs,
        reading_range_configs, reading_transform_config,
        config.entity_common_config(), io_context, on_batch_notify,
        hwmon_sysfs));
  }

  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) /
       sensor_attributes_static_.reading_transform().scale()) +
      sensor_attributes_static_.reading_transform().offset());
  StoreSensorData(std::make_shared<const SensorValue>(std::move(sensor_data)));
  State state;
  state.set_status(STATUS_READY);
  UpdateState(std::move(state));
}

bool PsuSensor::IsI3cPsuSensor(const PsuSensorType& sensor_type) {
  const auto* it =
      std::lower_bound(kSupportedI3cPsuSensorTypes.begin(),
                       kSupportedI3cPsuSensorTypes.end(), sensor_type);
  return it != kSupportedI3cPsuSensorTypes.end() && (*it == sensor_type);
}

PsuSensor::PsuSensor(Token token, PsuSensorType sensor_type,
                     SensorUnit sensor_unit, 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 ReadingTransformConfig& reading_transform_config,
                     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, sensor_unit, 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
