#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 "reading_transform_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,
      const ReadingTransformConfig &reading_transform_config);

  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_
