// Copyright 2018 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 COBALT_SRC_LOGGER_INTERNAL_METRICS_H_
#define COBALT_SRC_LOGGER_INTERNAL_METRICS_H_

#include <memory>
#include <queue>
#include <string>

#include "src/lib/util/protected_fields.h"
#include "src/logger/internal_metrics_config.cb.h"
#include "src/logger/logger_interface.h"
#include "src/public/diagnostics_interface.h"
#include "src/public/lib/registry_identifiers.h"
#include "src/registry/project.pb.h"

namespace cobalt::logger {

// InternalMetrics defines the methods used for collecting cobalt-internal
// metrics.
class InternalMetrics {
 public:
  // Returns a pointer to an InternalMetrics object which can be used for
  // collecting cobalt-internal metrics.
  //
  // |logger| the logger used to log internal metrics. If the pointer is null,
  // NoOpInternalMetrics will be used.
  //
  // |diagnostics|: The implementation to send diagnostic information about the
  // functioning of the Cobalt Core library. If null, no diagnostic information
  // will be sent.
  static std::unique_ptr<InternalMetrics> NewWithLogger(LoggerInterface* logger,
                                                        DiagnosticsInterface* diagnostics);

  // LoggerCalled (cobalt_internal::metrics::logger_calls_made_migrated) and
  // (cobalt_internal::metrics::per_project_logger_calls_made_migrated) are
  // logged for every call to Logger along with which method was called and
  // the project that called it.
  virtual void LoggerCalled(PerProjectLoggerCallsMadeMigratedMetricDimensionLoggerMethod method,
                            const Project& project) = 0;

  // cobalt_internal::metrics::bytes_uploaded is logged when the Clearcut
  // Uploader attempts or succeeds to upload observations from the device.
  virtual void BytesUploaded(BytesUploadedMetricDimensionStatus upload_status,
                             size_t byte_count) = 0;

  // cobalt_internal::metrics::per_project_bytes_uploaded_migrated is logged when
  // the Shipping Manager attempts or succeeds to store observations on the device.
  virtual void BytesUploaded(PerProjectBytesUploadedMigratedMetricDimensionStatus upload_status,
                             size_t byte_count,
                             const lib::ProjectIdentifier& project_identifier) = 0;

  // cobalt_internal::metrics::per_project_bytes_stored_migrated is logged when the
  // Observation Store attempts or succeeds to store observations on the device.
  virtual void BytesStored(PerProjectBytesStoredMigratedMetricDimensionStatus upload_status,
                           size_t byte_count, const lib::ProjectIdentifier& project_identifier) = 0;

  // cobalt_internal::metrics::idle_observation_upload_migrated is logged when the
  // Shipping Manager encrypts and uploads observations.
  virtual void IdleObservationUpload(
      IdleObservationUploadMigratedMetricDimensionDeviceState state) = 0;

  // cobalt_internal::metrics::inaccurate_clock_events_cached_migrated is logged when
  // the UndatedEventManager saves an event while the clock is inaccurate.
  virtual void InaccurateClockEventsCached(int64_t event_count) = 0;

  // cobalt_internal::metrics::inaccurate_clock_events_dropped_migrated is logged when
  // the UndatedEventManager drops a saved event while the clock is inaccurate and it
  // runs out of space.
  virtual void InaccurateClockEventsDropped(int64_t event_count) = 0;

  // cobalt_internal::metrics::set_software_distribution_info_called_migrated is logged
  // when the SystemData receives SoftwareDistributionInfo.
  virtual void SetSoftwareDistributionInfoCalled(
      SetSoftwareDistributionInfoCalledMigratedEventCodes event_codes) = 0;

  // Used to mark which class this disk usage is coming from. Can be:
  // - ObservationStore
  // - LocalAggregateStorage
  // - AggregateStore
  // - ObservationHistory
  using StorageClass = MetricsMetricDimensionStorageClass;

  // cobalt_internal::metrics::store_usage is used to track how much data is stored per-class on
  // disk.
  virtual void TrackDiskUsage(StorageClass storage_class, size_t bytes, int64_t max_bytes) = 0;
  void TrackDiskUsage(StorageClass storage_class, size_t bytes) {
    TrackDiskUsage(storage_class, bytes, -1);
  }

  // Flush queued internal metrics.
  virtual void Flush() = 0;

  // Returns true if this is an instance of the real implementation of
  // InternalMetrics that will really do internal logging and false if this
  // is a fake or no-op implementation.
  [[nodiscard]] virtual bool IsRealImpl() const = 0;

  virtual ~InternalMetrics() = default;
};

// NoOpInternalMetrics is to be used when the LoggerInterface* provided to the
// Logger constructor is nullptr. It stubs out all of the calls in the
// InternalMetrics interface, allowing code to safely make these calls even if
// no LoggerInterface* was provided.
class NoOpInternalMetrics : public InternalMetrics {
 public:
  void LoggerCalled(PerProjectLoggerCallsMadeMigratedMetricDimensionLoggerMethod method,
                    const Project& project) override {}

  void BytesUploaded(BytesUploadedMetricDimensionStatus upload_status, size_t byte_count) override {
  }

  void BytesUploaded(PerProjectBytesUploadedMigratedMetricDimensionStatus upload_status,
                     size_t byte_count, const lib::ProjectIdentifier& project_identifier) override {
  }

  void BytesStored(PerProjectBytesStoredMigratedMetricDimensionStatus upload_status,
                   size_t byte_count, const lib::ProjectIdentifier& project_identifier) override {}

  void IdleObservationUpload(
      IdleObservationUploadMigratedMetricDimensionDeviceState state) override {}

  void InaccurateClockEventsCached(int64_t event_count) override {}

  void InaccurateClockEventsDropped(int64_t event_count) override {}

  void SetSoftwareDistributionInfoCalled(
      SetSoftwareDistributionInfoCalledMigratedEventCodes event_codes) override {}

  // TODO(fxbug.dev/85571): NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
  void TrackDiskUsage(StorageClass storage_class, size_t bytes, int64_t max_bytes) override {}

  void Flush() override {}

  [[nodiscard]] bool IsRealImpl() const override { return false; }

  ~NoOpInternalMetrics() override = default;
};

// InternalMetricsImpl is the actual implementation of InternalMetrics. It is a
// wrapper around the (non nullptr) LoggerInterface* that was provided to the
// Logger constructor.
class InternalMetricsImpl : public InternalMetrics {
 public:
  InternalMetricsImpl(LoggerInterface* logger, DiagnosticsInterface* diagnostics);

  void LoggerCalled(PerProjectLoggerCallsMadeMigratedMetricDimensionLoggerMethod method,
                    const Project& project) override;

  void BytesUploaded(BytesUploadedMetricDimensionStatus upload_status, size_t byte_count) override;

  void BytesUploaded(PerProjectBytesUploadedMigratedMetricDimensionStatus upload_status,
                     size_t byte_count, const lib::ProjectIdentifier& project_identifier) override;

  void BytesStored(PerProjectBytesStoredMigratedMetricDimensionStatus upload_status,
                   size_t byte_count, const lib::ProjectIdentifier& project_identifier) override;

  void IdleObservationUpload(
      IdleObservationUploadMigratedMetricDimensionDeviceState state) override;

  void InaccurateClockEventsCached(int64_t event_count) override;

  void InaccurateClockEventsDropped(int64_t event_count) override;

  void SetSoftwareDistributionInfoCalled(
      SetSoftwareDistributionInfoCalledMigratedEventCodes event_codes) override;

  void TrackDiskUsage(StorageClass storage_class, size_t bytes, int64_t max_bytes) override;

  void Flush() override;

  [[nodiscard]] bool IsRealImpl() const override { return true; }

  ~InternalMetricsImpl() override = default;

 private:
  struct Protected {
    std::vector<std::function<void()>> queued_lambdas;
  };
  util::ProtectedFields<Protected> fields_;
  LoggerInterface* logger_;            // not owned
  DiagnosticsInterface* diagnostics_;  // not owned
};

// InternalMetricsPtr holds either a pointer to an InternalMetrics implementation, or a pointer to
// an instance of NoOpInternalMetrics. This class guarantees that the pointer is always valid.
class InternalMetricsPtr {
 public:
  InternalMetricsPtr() { reset(nullptr); }
  explicit InternalMetricsPtr(InternalMetrics* internal_metrics) { reset(internal_metrics); }

  void reset(InternalMetrics* internal_metrics) {
    if (internal_metrics) {
      ptr_ = internal_metrics;
    } else {
      ptr_ = &noop_internal_metrics_;
    }
  }

  [[nodiscard]] InternalMetrics* get() const { return ptr_; }
  InternalMetrics* operator->() const { return ptr_; }
  InternalMetrics& operator*() const { return *ptr_; }

 private:
  NoOpInternalMetrics noop_internal_metrics_;
  InternalMetrics* ptr_;
};

// InternalMetricsPauseWrapper wraps an instance of InternalMetrics, and adds the ability to pause
// logging. This is important to support pausing logging during batch logging to cobalt.
class InternalMetricsPauseWrapper : public InternalMetrics {
 public:
  explicit InternalMetricsPauseWrapper(InternalMetrics* internal_metrics)
      : wrapped_internal_metrics_(internal_metrics) {}

  void LoggerCalled(PerProjectLoggerCallsMadeMigratedMetricDimensionLoggerMethod method,
                    const Project& project) override {
    if (!paused_) {
      wrapped_internal_metrics_->LoggerCalled(method, project);
    }
  }

  void BytesUploaded(BytesUploadedMetricDimensionStatus upload_status, size_t byte_count) override {
    if (!paused_) {
      wrapped_internal_metrics_->BytesUploaded(upload_status, byte_count);
    }
  }

  void BytesUploaded(PerProjectBytesUploadedMigratedMetricDimensionStatus upload_status,
                     size_t byte_count, const lib::ProjectIdentifier& project_identifier) override {
    if (!paused_) {
      wrapped_internal_metrics_->BytesUploaded(upload_status, byte_count, project_identifier);
    }
  }

  void BytesStored(PerProjectBytesStoredMigratedMetricDimensionStatus upload_status,
                   size_t byte_count, const lib::ProjectIdentifier& project_identifier) override {
    if (!paused_) {
      wrapped_internal_metrics_->BytesStored(upload_status, byte_count, project_identifier);
    }
  }

  void IdleObservationUpload(
      IdleObservationUploadMigratedMetricDimensionDeviceState state) override {
    if (!paused_) {
      wrapped_internal_metrics_->IdleObservationUpload(state);
    }
  }

  void InaccurateClockEventsCached(int64_t event_count) override {
    if (!paused_) {
      wrapped_internal_metrics_->InaccurateClockEventsCached(event_count);
    }
  }

  void InaccurateClockEventsDropped(int64_t event_count) override {
    if (!paused_) {
      wrapped_internal_metrics_->InaccurateClockEventsDropped(event_count);
    }
  }

  void SetSoftwareDistributionInfoCalled(
      SetSoftwareDistributionInfoCalledMigratedEventCodes event_codes) override {
    if (!paused_) {
      wrapped_internal_metrics_->SetSoftwareDistributionInfoCalled(event_codes);
    }
  }

  void TrackDiskUsage(StorageClass storage_class, size_t bytes, int64_t max_bytes) override {
    if (!paused_) {
      wrapped_internal_metrics_->TrackDiskUsage(storage_class, bytes, max_bytes);
    }
  }

  // After PauseLogging is called, all calls to log internal metrics will be
  // ignored.
  void PauseLogging() { paused_ = true; }

  // Once ResumeLogging is called, calls to log internal metrics are will no
  // longer be ignored.
  void ResumeLogging() { paused_ = false; }

  void Flush() override { wrapped_internal_metrics_->Flush(); }

  [[nodiscard]] bool IsRealImpl() const override { return wrapped_internal_metrics_->IsRealImpl(); }

  void reset(InternalMetrics* internal_metrics) {
    wrapped_internal_metrics_.reset(internal_metrics);
  }

 private:
  InternalMetricsPtr wrapped_internal_metrics_;
  bool paused_ = false;
};

}  // namespace cobalt::logger

#endif  // COBALT_SRC_LOGGER_INTERNAL_METRICS_H_
