// 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_MEDIA_LIB_CODEC_IMPL_INCLUDE_LIB_MEDIA_CODEC_IMPL_CODEC_METRICS_H_
#define SRC_MEDIA_LIB_CODEC_IMPL_INCLUDE_LIB_MEDIA_CODEC_IMPL_CODEC_METRICS_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 <src/lib/cobalt/cpp/cobalt_event_builder.h>
#include <src/lib/cobalt/cpp/cobalt_logger.h>

#include <src/media/lib/metrics/metrics.cb.h>

// Methods of this class can be called on any thread.
class CodecMetrics final {
 public:
  // A nop instance so unit tests don't need to wire up cobalt.
  CodecMetrics() __TA_EXCLUDES(lock_);

  // !service_directory is ok.  If !service_directory, the instance will be a nop instance until
  // SetServiceDirectory() is called.
  CodecMetrics(std::shared_ptr<sys::ServiceDirectory> service_directory) __TA_EXCLUDES(lock_);

  ~CodecMetrics() __TA_EXCLUDES(lock_);

  // Set the ServiceDirectory from which to get fuchsia.cobalt.LoggerFactory.  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_);

  // 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.
  //
  // No attempt is made to flush pending events before driver exit or suspend, since this driver
  // isn't expected to unbind very often, if ever, and if we're suspending already then it's
  // unlikely that the pending cobalt events would be persisted anyway.
  void LogEvent(media_metrics::StreamProcessorEvents2MetricDimensionImplementation implementation,
                media_metrics::StreamProcessorEvents2MetricDimensionEvent event)
      __TA_EXCLUDES(lock_);

 private:
  class PendingCountsKey {
   public:
    PendingCountsKey(
        media_metrics::StreamProcessorEvents2MetricDimensionImplementation implementation,
        media_metrics::StreamProcessorEvents2MetricDimensionEvent event);

    media_metrics::StreamProcessorEvents2MetricDimensionImplementation implementation() const;
    media_metrics::StreamProcessorEvents2MetricDimensionEvent event() const;

   private:
    media_metrics::StreamProcessorEvents2MetricDimensionImplementation implementation_;
    media_metrics::StreamProcessorEvents2MetricDimensionEvent event_;
  };
  struct PendingCountsKeyHash {
    size_t operator()(const PendingCountsKey& key) const noexcept;
  };
  struct PendingCountsKeyEqual {
    bool operator()(const PendingCountsKey& lhs, const PendingCountsKey& rhs) const noexcept;
  };

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

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

  std::mutex lock_;

  // We have a separate async::Loop for each instance of cobalt::CobaltLogger, because CobaltLogger
  // requires that no async tasks posted by CobaltLogger out-live the CobaltLogger.  The easiest way
  // to achieve that is to give CobaltLogger its own async::Loop and Quit(), JoinThreads(),
  // Shutdown() that async::Loop before destroying the CobaltLogger.
  std::unique_ptr<async::Loop> loop_ = nullptr;

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

  // Don't bother with std::optional<> here - instead subtract kMinLoggingPeriod so we'll log
  // immediately the first time.
  zx::time last_flushed_ __TA_GUARDED(lock_) = zx::clock::get_monotonic() - kMinLoggingPeriod;

  // From component and event to event count.
  using PendingCounts =
      std::unordered_map<PendingCountsKey, int64_t, PendingCountsKeyHash, PendingCountsKeyEqual>;
  PendingCounts pending_counts_ __TA_GUARDED(lock_);
};

#endif  // SRC_MEDIA_LIB_CODEC_IMPL_INCLUDE_LIB_MEDIA_CODEC_IMPL_CODEC_METRICS_H_
