#ifndef THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_SENSOR_COLLECTOR_H_
#define THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_SENSOR_COLLECTOR_H_

#include <memory>
#include <optional>
#include <string>
#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;

  // Returns the sensor for the given sensor key.
  virtual std::shared_ptr<const Sensor> GetSensorBySensorKey(
      const std::string& sensor_key) 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_;
};

class EmptySensorCollector final : public SensorCollector {
 public:
  static std::unique_ptr<EmptySensorCollector> Create();

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

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

  // Returns the sensor for the given sensor key.
  std::shared_ptr<const Sensor> GetSensorBySensorKey(
      const std::string& sensor_key) const override;

  absl::Status ConfigureCollection(const Config& config) const override;

  std::shared_ptr<const Sensor> GetSensorByConfigNameAndSensorKey(
      const std::string& board_config_name,
      const std::string& sensor_key) const override;

  nlohmann::json GetSchedulerStats() const override;

  nlohmann::json ToJson() const override;
};

}  // namespace milotic_tlbmc

#endif  // THIRD_PARTY_MILOTIC_EXTERNAL_CC_TLBMC_COLLECTOR_SENSOR_COLLECTOR_H_
