#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_PSU_SENSOR_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_PSU_SENSOR_H_

#include <array>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
#include <vector>

#include "absl/base/thread_annotations.h"
#include "absl/status/statusor.h"
#include "boost/asio.hpp"  //NOLINT: boost::asio is commonly used in BMC
#include "boost/circular_buffer.hpp"  //NOLINT: boost is commonly used in BMC
#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 "sensor.pb.h"
#include "tlbmc/sensors/ixc_hwmon_based_sensor.h"
#include "tlbmc/sensors/sensor.h"

namespace milotic_tlbmc {

constexpr std::string_view kLabelSuffix = "_label";

/*
The following is the framework for adding different types of PSU sensors.
To add a new sensor type please do the following:
1. Add the new sensor type to the PsuSensorType enum below
2. Add the new sensor type to the kDefaultPsuSensorProperties array in
   psu_sensor.cc.
3. Add the new sensor file suffix to the kPsuSensorFileSuffixes array below
4. Add the new sensor label prefix to the kPsuSensorFilePrefixes array below

Example:
The peak power input file is found with a file that has the suffix
"_input_highest". In the EM config file, we attach the prefix "highest" to the
label to expose that sensor.
*/

enum class PsuSensorFileType : uint8_t {
  kDefault = 0,     // This is the default [sensor]_input file.
  kHighestPower,    // Power sensors have a special file for highest power:
                    // [power]_input_highest.
  kHighestDefault,  // Default sensors have a special file for highest default:
                    // [sensor]_highest.
  kUnknown,         // Non-standard sensor file.
};

constexpr std::array<std::string_view,
                     static_cast<size_t>(PsuSensorFileType::kUnknown)>
    kPsuSensorFileSuffixes = {"_input", "_input_highest", "_highest"};

constexpr std::array<std::string_view,
                     static_cast<size_t>(PsuSensorFileType::kUnknown)>
    kPsuSensorLabelPrefixes = {"", "highest", "highest"};

struct PsuSensorFileInfo {
  std::string file_prefix;
  PsuSensorFileType file_type;
};

class PsuSensor : public IXcHwmonBasedSensor {
 private:
  class Token;

 public:
  struct ReadingProperties {
    std::string_view label_type_name;
    double max_reading;
    double min_reading;
    double scale;
    double offset;
    SensorUnit sensor_unit;

    bool operator==(const ReadingProperties& other) const {
      return std::tie(max_reading, min_reading, scale, offset, sensor_unit) ==
             std::tie(other.max_reading, other.min_reading, other.scale,
                      other.offset, sensor_unit);
    }
  };
  // Load the device if not already loaded and returns a list of sensors that
  // can be used to read the temperature from the device. Note:
  // 1. The `io_context` must run only on a single thread.
  static absl::StatusOr<std::vector<std::shared_ptr<Sensor>>> Create(
      const PsuSensorConfig& config,
      const std::shared_ptr<boost::asio::io_context>& io_context,
      const HwmonSysfs& hwmon_sysfs,
      std::optional<NotificationCb> on_batch_notify = std::nullopt);

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

  ~PsuSensor() override = default;

  void HandleRefreshResult(const boost::system::error_code& error,
                           size_t bytes_read) override
      ABSL_LOCKS_EXCLUDED(sensor_data_mutex_);

  static bool IsI3cPsuSensor(const PsuSensorType& sensor_type);

 protected:
  PsuSensor() = default;
  explicit PsuSensor(const std::shared_ptr<boost::asio::io_context>& io_context)
      : IXcHwmonBasedSensor(io_context) {}

  // Returns the driver name for the given sensor type.
  static absl::StatusOr<std::string_view> GetDriverName(
      PsuSensorType sensor_type);

  // Given the config and the properties of the sensor, returns the reading
  // range configs.
  static absl::StatusOr<ReadingRangeConfigs> GetReadingRangeConfigs(
      const ReadingRangeConfigs& configs, const ReadingProperties& properties);

  // Given a label with digits (e.g., "vout1"), returns the default reading
  // properties of the sensor.
  static absl::StatusOr<ReadingProperties> GetPsuSensorProperties(
      std::string_view label);

  // Given an label, returns the unit of the sensor.
  static absl::StatusOr<SensorUnit> GetSensorUnit(std::string_view label);

  static std::string ApplyLabelModifications(std::string_view label,
                                             PsuSensorFileType file_type);

  static absl::StatusOr<std::string> ParseLabelFile(
      const boost::filesystem::path& hwmon_path, std::string_view file_prefix);

  // Given a sensor name, performs the transformation to append sensor unit and
  // create a unique name for the sensor.
  static std::string GetPsuSensorKey(std::string_view name,
                                     const PsuSensorConfig& config,
                                     PsuSensor::ReadingProperties properties);

  // Get the contents of the label of the sensor.
  static std::string GetLabel(const boost::filesystem::path& hwmon_path,
                              std::string_view file_prefix,
                              PsuSensorFileType file_type);

  static PsuSensorFileInfo GetPsuSensorFileInfo(std::string_view input_file);

 private:
  class Token {
   private:
    explicit Token() = default;
    friend PsuSensor;
  };

  const PsuSensorType sensor_type_ = PSU_SENSOR_TYPE0_UNKNOWN;
  const std::string sensor_name_;
};

}  // namespace milotic_tlbmc

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_PSU_SENSOR_H_
