#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 {

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

 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_
