#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_SENSOR_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_SENSOR_H_

#include <cstddef>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "absl/base/thread_annotations.h"
#include "absl/container/btree_set.h"
#include "absl/functional/any_invocable.h"
#include "absl/functional/function_ref.h"
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
#include "boost/circular_buffer.hpp"  //NOLINT: boost is commonly used in BMC
#include "entity_common_config.pb.h"
#include "i2c_common_config.pb.h"
#include "tlbmc/configs/subscription_config.h"
#include "resource.pb.h"
#include "sensor.pb.h"

namespace milotic_tlbmc {

std::string GetTrimmedSensorName(absl::string_view sensor_name);

// Any implementation of this interface must be thread-safe regarding the listed
// functions.
class Sensor {
 public:
  // Callback used export batch of sensor data.
  using NotificationCb = absl::FunctionRef<void(
      std::vector<std::shared_ptr<const SensorValue>> &&)>;

  static SensorAttributesStatic CreateStaticAttributes(
      absl::string_view sensor_name, const SensorUnit &sensor_unit,
      const I2cCommonConfig &i2c_common_config,
      const EntityCommonConfig &entity_common_config,
      const ThresholdConfigs &threshold_configs,
      const ReadingRangeConfigs &reading_range_configs);

  virtual ~Sensor() = default;

  // Returns the latest sensor reading.
  std::shared_ptr<const SensorValue> GetSensorData() const
      ABSL_LOCKS_EXCLUDED(sensor_data_mutex_) {
    absl::MutexLock lock(&sensor_data_mutex_);
    return sensor_data_.empty() ? nullptr : sensor_data_.back();
  }

  std::vector<std::shared_ptr<const SensorValue>> GetSensorDataHistory() const
      ABSL_LOCKS_EXCLUDED(sensor_data_mutex_) {
    absl::MutexLock lock(&sensor_data_mutex_);
    return {sensor_data_.begin(), sensor_data_.end()};
  }

  std::vector<std::shared_ptr<const SensorValue>> GetSensorDataHistorySince(
      absl::Time start_time) const ABSL_LOCKS_EXCLUDED(sensor_data_mutex_);

  // Refreshes the sensor data once asynchronously. The sensor data will be
  // updated when the refresh is done. On errors, nullptr will be fed to the
  // callback. Detailed error message can be found in the sensor's state.
  // The `callback` will be called when the refresh is done with the SensorData
  // that has been refreshed or nullptr if there is an error. The `callback` can
  // be nullptr. The callback is supposed to be blocking.
  virtual void RefreshOnceAsync(
      absl::AnyInvocable<void(const std::shared_ptr<const SensorValue> &)>
          callback) = 0;

  // Returns the key of the sensor. A key shall be constant for a sensor's
  // lifetime.
  std::string GetKey() const {
    return sensor_attributes_static_.attributes().key();
  }

  // Returns the config name of the board that contains this sensor.
  std::string GetConfigName() const {
    return sensor_attributes_static_.entity_common_config().board_config_name();
  }

  SensorAttributesDynamic GetSensorAttributesDynamic() const {
    absl::MutexLock lock(&sensor_attributes_dynamic_mutex_);
    return sensor_attributes_dynamic_;
  }

  const SensorAttributesStatic &GetSensorAttributesStatic() const {
    return sensor_attributes_static_;
  }

  // Subscribes to the sensor data.
  absl::Status Subscribe(const SubscriptionParams *subscription_params);
  // Deletes an existing subscription.
  absl::Status Unsubscribe(const SubscriptionParams *subscription_params);
  void UpdateState(State &&state);
  // Resize the buffer for the sensor.
  void ResizeBuffer(size_t buffer_size);

 protected:
  Sensor(SensorAttributesStatic &&sensor_attributes_static,
         std::optional<NotificationCb> notification_cb)
      : sensor_attributes_static_(std::move(sensor_attributes_static)),
        sensor_data_(static_cast<size_t>(
            sensor_attributes_static_.entity_common_config().queue_size())),
        notification_cb_(notification_cb) {}
  Sensor() : sensor_data_(1) {
    DLOG(INFO) << "Sensor created with default queue size of "
               << sensor_data_.capacity();
  }

  // Buffers the sensor data and notifies the subscribers if the batch size
  // reaches the threshold.
  void StoreSensorData(const std::shared_ptr<const SensorValue> &sensor_data)
      ABSL_LOCKS_EXCLUDED(sensor_data_mutex_, sensor_attributes_dynamic_mutex_);

  const SensorAttributesStatic sensor_attributes_static_;

  mutable absl::Mutex sensor_attributes_dynamic_mutex_;
  SensorAttributesDynamic sensor_attributes_dynamic_
      ABSL_GUARDED_BY(sensor_attributes_dynamic_mutex_);

  mutable absl::Mutex sensor_data_mutex_;
  // Front() returns the oldest data.
  boost::circular_buffer<std::shared_ptr<const SensorValue>> sensor_data_
      ABSL_GUARDED_BY(sensor_data_mutex_);

  // The set of batch sizes that are subscribed to the sensor.
  absl::btree_set<const SubscriptionParams *, SubscriptionParams::Compare>
      subscription_params_ ABSL_GUARDED_BY(sensor_attributes_dynamic_mutex_);
  // Callback to be invoked when the batch size reaches the threshold.
  // Not locked: The callback is instantiated in the constructor and is
  // supposed to be invoked from a single io_context thread.
  const std::optional<NotificationCb> notification_cb_ = std::nullopt;
};

}  // namespace milotic_tlbmc

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_SENSORS_SENSOR_H_
