#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 "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>, 8>
    kSupportedPsuSensorTypes = {
        // go/keep-sorted start
        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"},
        // 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}},
        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}},
        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}},
        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}},
        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}},
        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}},
        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}},
        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}},
        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}}
        // go/keep-sorted end
};

constexpr std::array<std::pair<std::string_view, SensorUnit>, 5>
    kInputWithoutDigitsToUnit = {
        // go/keep-sorted start
        std::pair<std::string_view, SensorUnit>{"curr",
                                                SensorUnit::UNIT_AMPERE},
        std::pair<std::string_view, SensorUnit>{"in", SensorUnit::UNIT_VOLT},
        std::pair<std::string_view, SensorUnit>{"power", SensorUnit::UNIT_WATT},
        std::pair<std::string_view, SensorUnit>{
            "temp", SensorUnit::UNIT_DEGREE_CELSIUS},
        std::pair<std::string_view, SensorUnit>{"voltage",
                                                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;
}

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

absl::StatusOr<SensorUnit> PsuSensor::GetSensorUnit(
    std::string_view input_file) {
  std::string_view input_file_no_digit = input_file;
  std::size_t first_index = input_file_no_digit.find_first_of("0123456789");
  if (first_index == std::string_view::npos) {
    return absl::InvalidArgumentError(absl::Substitute(
        "Failed to find the last non-digit character in $0", input_file));
  }
  input_file_no_digit = input_file_no_digit.substr(0, first_index);
  const auto* it = std::lower_bound(
      kInputWithoutDigitsToUnit.begin(), kInputWithoutDigitsToUnit.end(),
      std::pair<std::string_view, SensorUnit>{input_file_no_digit,
                                              SensorUnit::UNIT_UNKNOWN},
      TypeComparator<std::string_view, SensorUnit>());
  if (it == kInputWithoutDigitsToUnit.end() ||
      it->first != input_file_no_digit) {
    return absl::InvalidArgumentError(absl::Substitute(
        "Unsupported sensor input file: $0", input_file_no_digit));
  }
  return it->second;
}

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()));

  // E.g., /sys/bus/i2c/devices/20-0040/hwmon/hwmon18/
  ECCLESIA_ASSIGN_OR_RETURN(
      boost::filesystem::path hwmon_path,
      I2cHwmonBasedSensor::CreateDeviceAndReturnsHwmonPath(
          i2c_common_config, driver_name, i2c_sysfs));

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

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

  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));
    ECCLESIA_ASSIGN_OR_RETURN(SensorUnit sensor_unit,
                              GetSensorUnit(input_file));

    std::string sensor_key = name;
    if (sensor_key.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
      sensor_key = absl::StrCat(config.name(), "_", properties.label_type_name);
      std::replace(sensor_key.begin(), sensor_key.end(), ' ', '_');
    }
    switch (sensor_unit) {
      case SensorUnit::UNIT_AMPERE:
        sensor_key = absl::StrCat("current_", sensor_key);
        break;
      case SensorUnit::UNIT_VOLT:
        sensor_key = absl::StrCat("voltage_", sensor_key);
        break;
      case SensorUnit::UNIT_WATT:
        sensor_key = absl::StrCat("power_", sensor_key);
        break;
      case SensorUnit::UNIT_DEGREE_CELSIUS:
        sensor_key = absl::StrCat("temperature_", sensor_key);
        break;
      default:
        break;
    }

    sensors.push_back(std::make_shared<PsuSensor>(
        Token(), config.type(), 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;
  uint64_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
