#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_INTEL_CPU_SENSOR_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_INTEL_CPU_SENSOR_H_

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

#include "google/protobuf/duration.pb.h"
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/log/log.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "boost/asio.hpp"  // NOLINT: boost::asio is commonly used in BMC
#include "boost/asio/error.hpp"  // NOLINT
#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
#include "boost/system/detail/error_code.hpp"  // NOLINT: boost::asio is commonly used in BMC
#include "intel_cpu_sensor_config.pb.h"
#include "threshold_config.pb.h"
#include "tlbmc/sensors/peci_hwmon_based_sensor.h"
// NOLINTNEXTLINE: keep this so BUILD file will keep liburing
#include "liburing.h"  // IWYU pragma: keep
#include "hal_common_config.pb.h"
#include "tlbmc/hal/sysfs/peci.h"
#include "resource.pb.h"
#include "sensor.pb.h"
#include "tlbmc/sensors/sensor.h"
#include "re2/re2.h"

namespace milotic_tlbmc {

class IntelCpuSensor : public PeciHwmonBasedSensor {
 private:
  class Token;

 public:
  // State of the CPU associated with the sensor.
  enum class CpuState : uint8_t {
    OFF = 0,   // host powered down
    ON = 1,    // host powered on
    READY = 2  // host powered on and mem test passed - fully ready
  };

  struct ReadingProperties {
    double max_reading;
    double min_reading;
    SensorUnit sensor_unit;

    bool operator==(const ReadingProperties& other) const {
      return std::tie(max_reading, min_reading, sensor_unit) ==
             std::tie(other.max_reading, other.min_reading, sensor_unit);
    }
  };

  static constexpr const unsigned int kRankNumMax = 8;
  static constexpr const unsigned int kScaleFactor = 1000;
  static constexpr std::array<absl::string_view, 3> kHiddenProperties = {
      "Tcontrol", "Tthrottle", "Tjmax"};

  static constexpr LazyRE2 kCpuTempRegex = {
      R"(peci-cputemp.+/hwmon/hwmon\d+/name$)"};
  static constexpr LazyRE2 kDimmTempRegex = {
      R"(peci-dimmtemp.+/hwmon/hwmon\d+/name$)"};
  static constexpr absl::string_view kHwmonNameRegex = {
      R"(peci-$0/$0-$1/peci[-_].+/hwmon/hwmon\d+/name$$)"};
  static constexpr LazyRE2 kInputRegex = {
      R"((temp|power)\d+_(input|average|cap)$)"};

  static constexpr LazyRE2 kDimmSensorNameRegex = {R"(DIMM\d+)"};

  IntelCpuSensor(Token token, IntelCpuSensorType sensor_type,
                 SensorUnit sensor_unit, const std::string& input_dev_path,
                 const std::string& sensor_name,
                 const std::string& sensor_label,
                 const HalCommonConfig& hal_common_config,
                 const ThresholdConfigs& threshold_configs,
                 const ReadingRangeConfigs& reading_range_configs,
                 const ReadingTransformConfig& reading_transform_config,
                 const EntityCommonConfig& entity_common_config,
                 double dts_offset,
                 const std::shared_ptr<boost::asio::io_context>& io_context,
                 std::optional<NotificationCb> on_batch_notify,
                 const PeciSysfs& peci_sysfs);
  ~IntelCpuSensor() override = default;

  static absl::StatusOr<std::vector<std::shared_ptr<Sensor>>>
  CreateInitialSensors(
      const IntelCpuSensorConfig& sensor_config,
      const std::shared_ptr<boost::asio::io_context>& io_context,
      const PeciSysfs& peci_sysfs,
      std::optional<NotificationCb> on_batch_notify = std::nullopt);

  void Reinitialize(absl::AnyInvocable<void(absl::Status)> callback) override;

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

  static std::vector<boost::filesystem::path> FindFiles(
      const boost::filesystem::path& root_dir, const RE2& regex, int max_depth);

  static std::string CreateSensorName(absl::string_view label, uint32_t cpu_id);

  static RelatedItem CreateRelatedItem(
      absl::string_view sensor_name, const IntelCpuSensorConfig& sensor_config);

 protected:
  IntelCpuSensor() = default;

  // For unit testing only.
  explicit IntelCpuSensor(
      const PeciSysfs& peci_sysfs, const IntelCpuSensorConfig& config,
      const std::string& sensor_label,
      const std::shared_ptr<boost::asio::io_context>& io_context,
      const std::vector<uint32_t>& retry_delays);

  static absl::StatusOr<std::tuple<std::string, std::string, std::string>>
  SplitInputFile(const boost::filesystem::path& input_file_path);

  void ParseThresholdsFromHwmonFiles();

  absl::flat_hash_map<std::string, std::string> CreateLabelToInputFileMap(
      const boost::filesystem::path& peci_device_path,
      const HalCommonConfig& hal_config);

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

  absl::Status ReinitializeInternal();

  void ReinitializeWithRetry(absl::AnyInvocable<void(absl::Status)> callback,
                             uint32_t attempts_left);

  const IntelCpuSensorType sensor_type_ = INTEL_CPU_SENSOR_TYPE0_UNKNOWN;
  const std::vector<uint32_t> retry_delays_ = {5, 30, 60};
  const std::string sensor_name_;
  const std::string sensor_label_;
  const double dts_offset_ = 0.0;

  boost::asio::steady_timer retry_timer_;
};

}  // namespace milotic_tlbmc

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_INTEL_CPU_SENSOR_H_
