#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 "i2c_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/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 = 6,
                                         .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 = 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 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(),
          ReadingTransformConfig(), 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 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.i2c_common_config(), threshold_configs,
        reading_range_configs, reading_transform_config,
        config.entity_common_config(), 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) /
       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));
}

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 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)
    : I2cHwmonBasedSensor(input_dev_path, io_context,
                          CreateStaticAttributes(
                              sensor_name, sensor_unit, i2c_common_config,
                              entity_common_config, threshold_configs,
                              reading_range_configs, reading_transform_config),
                          on_batch_notify),
      sensor_type_(sensor_type),
      sensor_name_(sensor_name),
      board_config_name_(entity_common_config.board_config_name()) {}

}  // namespace milotic_tlbmc
