#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_SENSOR_COLLECTOR_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_SENSOR_COLLECTOR_H_

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

#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/synchronization/mutex.h"
#include "boost/asio.hpp"  //NOLINT: boost::asio is commonly used in BMC
#include "thread/thread.h"
#include "time/clock.h"
#include "nlohmann/json.hpp"
#include "tlbmc/collector/collector.h"
#include "tlbmc/configs/entity_config.h"
#include "tlbmc/hal/sysfs/i2c.h"
#include "sensor.pb.h"
#include "tlbmc/scheduler/scheduler.h"
#include "tlbmc/sensors/sensor.h"

namespace milotic_tlbmc {

struct ThreadManager {
  explicit ThreadManager(ecclesia::Clock* clock)
      : task_scheduler(std::make_unique<TaskScheduler>(clock)) {}

  ~ThreadManager();

  std::vector<std::unique_ptr<ecclesia::ThreadInterface>> threads;
  std::vector<std::shared_ptr<boost::asio::io_context>> io_contexts;
  std::vector<
      boost::asio::executor_work_guard<boost::asio::io_context::executor_type>>
      work_guards;
  std::unique_ptr<TaskScheduler> task_scheduler;
  // This is used to store the task id of the sensor to allow managing the
  // lifetime of the sensor.
  absl::flat_hash_map<std::string, int> sensor_key_to_task_id;
};

// Register a callback to be invoked when a collector refreshes data.
// This class is thread safe.
// Used mostly for testing.
class SensorNotification {
 public:
  explicit SensorNotification(
      absl::AnyInvocable<void(const std::shared_ptr<const SensorValue>&)>
          callback)
      : callback_(std::move(callback)) {}

  void NotifyWithData(const std::shared_ptr<const SensorValue>& sensor_data)
      ABSL_LOCKS_EXCLUDED(mutex_) {
    absl::MutexLock lock(&mutex_);
    callback_(sensor_data);
  }

 private:
  mutable absl::Mutex mutex_;
  absl::AnyInvocable<void(const std::shared_ptr<const SensorValue>&)> callback_
      ABSL_GUARDED_BY(mutex_);
};

class SensorCollector : public Collector {
 public:
  // Parameters for creating a sensor collector.
  struct Params {
    const EntityConfig& entity_config;
    const I2cSysfs& i2c_sysfs;
    // Using a thread factory to allow us to switch to fibers in future when it
    // gets open sourced.
    ecclesia::ThreadFactoryInterface* thread_factory =
        ecclesia::GetDefaultThreadFactory();
    SensorNotification* refresh_notification = nullptr;
    ecclesia::Clock* clock = ecclesia::Clock::RealClock();
    // Typically used when we want to override the default sensor sampling
    // interval.
    std::optional<int> override_sensor_sampling_interval_ms = std::nullopt;
  };

  // Creates a sensor collector.
  static absl::StatusOr<std::unique_ptr<SensorCollector>> Create(
      const Params& params);

  // Returns the sorted list of sensor names contained by the given Config name.
  virtual std::vector<std::string> GetAllSensorKeysByConfigName(
      const std::string& board_config_name) const;

  // Returns all the sensors sorted by sensor name.
  virtual std::vector<std::shared_ptr<const Sensor>> GetAllSensors() const;

  // Configures the sensor collector.
  // A key usage of this method is to configure the sampling interval of the
  // data.
  absl::Status ConfigureCollection(const Config& config) const override;

  // Returns the sensor for the given board config name and given sensor
  // key.
  virtual std::shared_ptr<const Sensor> GetSensorByConfigNameAndSensorKey(
      const std::string& board_config_name,
      const std::string& sensor_key) const;

  nlohmann::json GetSchedulerStats() const override {
    return thread_manager_->task_scheduler->ToJson();
  }

  nlohmann::json ToJson() const override;

 protected:
  // Protected constructor to allow mocking.
  SensorCollector() = default;

 private:
  SensorCollector(std::vector<std::shared_ptr<Sensor>>&& sensors,
                  std::unique_ptr<ThreadManager> thread_manager,
                  const SensorNotification* refresh_notification);

  // In today's use case, we will never have dynamic set of sensors. All sensors
  // are created during daemon start-up.
  // First dimension: board_config_name
  // Second dimension: sensor_key
  const absl::flat_hash_map<
      std::string, absl::flat_hash_map<std::string, std::shared_ptr<Sensor>>>
      sensor_table_;
  std::unique_ptr<ThreadManager> thread_manager_;
  const SensorNotification* refresh_notification_;
};

}  // namespace milotic_tlbmc

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_SENSOR_COLLECTOR_H_
