#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 {
 protected:
  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,
            const std::string& input_dev_path,
            const HalCommonConfig& hal_common_config,
            const EntityCommonConfig& entity_common_config,
            const SensorInstanceProperties& sensor_instance_properties,
            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 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(
      const EntityCommonConfig& entity_common_config,
      const SensorInstanceProperties& instance_properties,
      const PsuSensor::ReadingProperties& reading_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);

  static absl::StatusOr<std::shared_ptr<Sensor>> CreateFailedSensor(
      const std::string& label, const PsuSensorConfig& config,
      const SensorInstanceProperties& sensor_instance_properties,
      const std::shared_ptr<boost::asio::io_context>& io_context,
      const HwmonSysfs& hwmon_sysfs,
      std::optional<NotificationCb> on_batch_notify,
      std::string_view error_message);

  static absl::StatusOr<std::shared_ptr<PsuSensor>> CreatePsuSensor(
      const std::string& label, const std::string& input_dev_path,
      const PsuSensorConfig& config,
      const SensorInstanceProperties& sensor_instance_properties,
      const std::shared_ptr<boost::asio::io_context>& io_context,
      std::optional<NotificationCb> on_batch_notify,
      const HwmonSysfs& hwmon_sysfs);

  class Token {
   public:
    explicit Token() = default;
  };

  const PsuSensorType sensor_type_ = PSU_SENSOR_TYPE0_UNKNOWN;
};

}  // namespace milotic_tlbmc

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_PSU_SENSOR_H_
