// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_LIB_METRICS_BUFFER_METRICS_BUFFER_H_
#define SRC_LIB_METRICS_BUFFER_METRICS_BUFFER_H_

#include <fidl/fuchsia.io/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/sys/cpp/service_directory.h>

#include <memory>
#include <unordered_map>
#include <unordered_set>

#include "src/lib/metrics_buffer/metrics_impl.h"

namespace cobalt {

class MetricsBuffer;

// This class is a convenience interface which remembers a metric_id.
class MetricBuffer {
 public:
  MetricBuffer(const MetricBuffer& to_copy) = delete;
  MetricBuffer& operator=(const MetricBuffer& to_copy) = delete;
  MetricBuffer(MetricBuffer&& to_move) = default;
  MetricBuffer& operator=(MetricBuffer&& to_move) = default;
  ~MetricBuffer() = default;

  void LogEvent(std::vector<uint32_t> dimension_values);
  void LogEventCount(std::vector<uint32_t> dimension_values, uint32_t count);

 private:
  friend class MetricsBuffer;
  MetricBuffer(std::shared_ptr<MetricsBuffer> parent, uint32_t metric_id);
  std::shared_ptr<MetricsBuffer> parent_;
  uint32_t metric_id_ = 0;
};

// This class is a convenience interface which remembers a metric_id.
class StringMetricBuffer {
 public:
  StringMetricBuffer(const StringMetricBuffer& to_copy) = delete;
  StringMetricBuffer& operator=(const StringMetricBuffer& to_copy) = delete;
  StringMetricBuffer(StringMetricBuffer&& to_move) = default;
  StringMetricBuffer& operator=(StringMetricBuffer&& to_move) = default;
  ~StringMetricBuffer() = default;

  void LogString(std::vector<uint32_t> dimension_values, std::string string_value);

 private:
  friend class MetricsBuffer;
  StringMetricBuffer(std::shared_ptr<MetricsBuffer> parent, uint32_t metric_id);
  std::shared_ptr<MetricsBuffer> parent_;
  uint32_t metric_id_ = 0;
};

struct ExponentialIntegerBuckets {
  int64_t floor;
  uint32_t num_buckets;
  uint32_t initial_step;
  uint32_t step_multiplier;
};

struct LinearIntegerBuckets {
  int64_t floor;
  uint32_t num_buckets;
  uint32_t step_size;
};

struct HistogramInfo {
  uint32_t metric_id = 0;
  std::variant<ExponentialIntegerBuckets, LinearIntegerBuckets> buckets;
};

// If metrics.cb.h codegen provides a non-macro way in future, switch to that.
#define COBALT_EXPONENTIAL_HISTOGRAM_INFO(base_name)                                      \
  [] {                                                                                    \
    ::cobalt::ExponentialIntegerBuckets buckets;                                          \
    buckets.floor = base_name##IntBucketsFloor;                                           \
    buckets.num_buckets = base_name##IntBucketsNumBuckets;                                \
    buckets.initial_step = base_name##IntBucketsInitialStep;                              \
    buckets.step_multiplier = base_name##IntBucketsStepMultiplier;                        \
    return ::cobalt::HistogramInfo{.metric_id = base_name##MetricId, .buckets = buckets}; \
  }()

#define COBALT_LINEAR_HISTOGRAM_INFO(base_name)                                           \
  [] {                                                                                    \
    ::cobalt::LinearIntegerBuckets buckets;                                               \
    buckets.floor = base_name##IntBucketsFloor;                                           \
    buckets.num_buckets = base_name##IntBucketsNumBuckets;                                \
    buckets.step_size = base_name##IntBucketsStepSize;                                    \
    return ::cobalt::HistogramInfo{.metric_id = base_name##MetricId, .buckets = buckets}; \
  }()

// This class is a convenience interface which remembers metric_id + bucket_config, and calculates
// which bucket for the caller.
class HistogramMetricBuffer {
 public:
  HistogramMetricBuffer(const HistogramMetricBuffer& to_copy) = delete;
  HistogramMetricBuffer& operator=(const HistogramMetricBuffer& to_copy) = delete;
  HistogramMetricBuffer(HistogramMetricBuffer&& to_move) = default;
  HistogramMetricBuffer& operator=(HistogramMetricBuffer&& to_move) = default;
  ~HistogramMetricBuffer() = default;

  // This computes which histogram bucket, and adds 1 to the tally of that bucket.
  void LogValue(std::vector<uint32_t> dimension_values, int64_t value);

 private:
  friend class MetricsBuffer;
  // For the second parameter, see COBALT_EXPONENTIAL_HISTOGRAM_INFO() and
  // COBALT_LINEAR_HISTOGRAM_INFO() defined above.
  HistogramMetricBuffer(std::shared_ptr<MetricsBuffer> parent, HistogramInfo histogram_info);
  std::shared_ptr<MetricsBuffer> parent_;
  HistogramInfo histogram_info_;

  // This info corresponds to fields of cobalt IntegerBucketConfig. We can't depend on
  // cobalt buckets_config from here because it depends on syslog.
  std::vector<int64_t> floors_;
};

// The purpose of this class is to ensure the rate of messages to Cobalt stays reasonable, per
// Cobalt's rate requirement/recommendation in the Cobalt docs.
//
// Typically it'll make sense to only have one of these per process, but that's not enforced.
//
// Methods of this class can be called on any thread.
class MetricsBuffer final : public std::enable_shared_from_this<MetricsBuffer> {
 public:
  // Initially a noop instance, so unit tests don't need to wire up cobalt.  Call
  // SetServiceDirectory() to enable and start logging.
  static std::shared_ptr<MetricsBuffer> Create(uint32_t project_id);

  // !service_directory is ok.  If !service_directory, the instance will be a nop instance until
  // SetServiceDirectory() is called.
  static std::shared_ptr<MetricsBuffer> Create(
      uint32_t project_id, std::shared_ptr<sys::ServiceDirectory> service_directory);

  ~MetricsBuffer() __TA_EXCLUDES(lock_);

  // Set the ServiceDirectory from which to get fuchsia.metrics.MetricEventLoggerFactory.  This can
  // be nullptr. This can be called again, regardless of whether there was already a previous
  // ServiceDirectory. Previously-queued events may be lost (especially recently-queued events) when
  // switching to a new ServiceDirectory.
  void SetServiceDirectory(std::shared_ptr<sys::ServiceDirectory> service_directory)
      __TA_EXCLUDES(lock_);

  // This specifies the minimum amount of time between logging batches to cobalt.  If enough
  // different metrics have accumulated to force more than one message to cobalt, then more than
  // one message is possible, but typically a single message will be sent to cobalt no more often
  // than this.  In unit tests we use this to turn the min_logging_period way down so that tests can
  // finish faster.
  void SetMinLoggingPeriod(zx::duration min_logging_period);

  // Log the event as EVENT_COUNT, with period_duration_micros 0, possibly aggregating with any
  // other calls to this method with the same component and event wihtin a short duration to limit
  // the rate of FIDL calls to Cobalt, per the rate requirement/recommendation in the Cobalt docs.
  void LogEvent(uint32_t metric_id, std::vector<uint32_t> dimension_values) __TA_EXCLUDES(lock_);

  void LogEventCount(uint32_t metric_id, std::vector<uint32_t> dimension_values, uint32_t count);

  // The string_value is not an arbitrary string; it must be one of the potential strings defined in
  // the metric definition, or the string_value ends up getting ignored.
  void LogString(uint32_t metric_id, std::vector<uint32_t> dimension_values,
                 std::string string_value);

  // Use sparingly, only when it's appropriate to force the counts to flush to Cobalt, which will
  // typically only be before orderly exit or in situations like driver suspend.  Over-use of this
  // method will break the purpose of using this class, which is to ensure the rate of messages to
  // Cobalt stays reasonable.
  void ForceFlush() __TA_EXCLUDES(lock_);

  MetricBuffer CreateMetricBuffer(uint32_t metric_id);
  StringMetricBuffer CreateStringMetricBuffer(uint32_t metric_id);
  HistogramMetricBuffer CreateHistogramMetricBuffer(HistogramInfo histogram_info);

 private:
  friend class HistogramMetricBuffer;

  // This computes which histogram bucket, and adds 1 to the tally of that bucket.
  void LogHistogramValue(const HistogramInfo& histogram_info, std::vector<int64_t>& floors,
                         std::vector<uint32_t> dimension_values, int64_t value);

  explicit MetricsBuffer(uint32_t project_id) __TA_EXCLUDES(lock_);

  MetricsBuffer(uint32_t project_id, std::shared_ptr<sys::ServiceDirectory> service_directory)
      __TA_EXCLUDES(lock_);

  class MetricKey {
   public:
    MetricKey(uint32_t metric_id, std::vector<uint32_t> dimension_values);

    uint32_t metric_id() const;
    const std::vector<uint32_t>& dimension_values() const;

   private:
    uint32_t metric_id_ = 0;
    std::vector<uint32_t> dimension_values_;
  };
  struct MetricKeyHash {
    size_t operator()(const MetricKey& key) const noexcept;

   private:
    std::hash<uint32_t> hash_uint32_;
  };
  struct MetricKeyEqual {
    bool operator()(const MetricKey& lhs, const MetricKey& rhs) const noexcept;
  };

  // We don't keep a count per string; instead we collapse out any additional string instances per
  // flush period, since each tally of a string would require an additional item in the batch. We
  // want to avoid creating a large number of items in a batch or a large number of batches due to
  // a noisy string. We also want to avoid using unbounded memory in the MetricsBuffer. We could
  // achieve this with a cap on how many instances of the same string we're willing to buffer and
  // batch, but for now we just cap at buffering 1 of a given string at any given time.
  class PendingStringsItem {
   public:
    PendingStringsItem(uint32_t metric_id, std::vector<uint32_t> dimension_values,
                       std::string string_value);

    uint32_t metric_id() const;
    const std::vector<uint32_t>& dimension_values() const;
    const std::string& string_value() const;

   private:
    uint32_t metric_id_ = 0;
    std::vector<uint32_t> dimension_values_;
    std::string string_value_;
  };
  struct PendingStringsItemHash {
    size_t operator()(const PendingStringsItem& item) const noexcept;

   private:
    std::hash<uint32_t> hash_uint32_;
    std::hash<std::string> hash_string_;
  };
  struct PendingStringsItemEqual {
    bool operator()(const PendingStringsItem& lhs, const PendingStringsItem& rhs) const noexcept;
  };

  void TryPostFlushCountsLocked() __TA_REQUIRES(lock_);
  void FlushPendingEventCounts() __TA_EXCLUDES(lock_);

  static constexpr zx::duration kDefaultMinLoggingPeriod = zx::sec(5);

  std::mutex lock_;

  const uint32_t project_id_{};

  // For historical reasons, we have a separate async::Loop for each instance of
  // cobalt::MetricsImpl. We only SetServiceDirectory() once in non-test scenarios, so outside tests
  // we'll only ever create one async::Loop.
  std::unique_ptr<async::Loop> loop_;

  std::unique_ptr<cobalt::MetricsImpl> cobalt_logger_ __TA_GUARDED(lock_);

  zx::time last_flushed_ __TA_GUARDED(lock_) = zx::time::infinite_past();

  // From component and event to event count.
  using PendingCounts = std::unordered_map<MetricKey, int64_t, MetricKeyHash, MetricKeyEqual>;
  PendingCounts pending_counts_ __TA_GUARDED(lock_);

  // We don't keep a count per string; instead we collapse out any additional string instances per
  // flush period, since each tally of a string would require an additional item in the batch. We
  // want to avoid creating a large number of items in a batch or a large number of batches due to
  // a noisy string. We also want to avoid using unbounded memory in the MetricsBuffer. We could
  // achieve this with a cap on how many instances of the same string we're willing to buffer and
  // batch, but for now we just cap at buffering 1 of a given string at any given time.
  using PendingStrings =
      std::unordered_map<MetricKey, std::unordered_set<std::string>, MetricKeyHash, MetricKeyEqual>;
  PendingStrings pending_strings_ __TA_GUARDED(lock_);

  // key - bucket index
  // value - how many tallies to add to bucket
  using PendingBuckets = std::unordered_map<uint32_t, uint32_t>;
  using PendingHistograms =
      std::unordered_map<MetricKey, PendingBuckets, MetricKeyHash, MetricKeyEqual>;

  PendingHistograms pending_histograms_ __TA_GUARDED(lock_);

  zx::duration min_logging_period_ = kDefaultMinLoggingPeriod;
};

}  // namespace cobalt

#endif  // SRC_LIB_METRICS_BUFFER_METRICS_BUFFER_H_
