// 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_OBSERVATION_STORE_OBSERVATION_STORE_H_
#define COBALT_SRC_OBSERVATION_STORE_OBSERVATION_STORE_H_

#include <deque>
#include <map>
#include <memory>
#include <string>
#include <vector>

#include "src/lib/util/encrypted_message_util.h"
#include "src/logger/internal_metrics.h"
#include "src/logger/logger_interface.h"
#include "src/observation_store/observation_store_internal.pb.h"
#include "src/pb/envelope.pb.h"
#include "src/pb/observation_batch.pb.h"

namespace cobalt {
namespace observation_store {

// A specification to identify a single Cobalt report.
struct ReportSpec {
  uint32_t customer_id;
  uint32_t project_id;
  uint32_t metric_id;
  uint32_t report_id;

  bool operator<(const ReportSpec& o) const {
    return std::tie(customer_id, project_id, metric_id, report_id) <
           std::tie(o.customer_id, o.project_id, o.metric_id, o.report_id);
  }
};

// ObservationStoreWriterInterface is an abstract interface to a store
// of Observations, to be used by code that writes to this store. This is
// isolated into an abstract interface that can be mocked out in tests.
class ObservationStoreWriterInterface {
 public:
  virtual ~ObservationStoreWriterInterface() = default;

  enum StoreStatus {
    // StoreObservation() succeeded.
    kOk = 0,
    // The Observation was not added to the store because it is too big.
    kObservationTooBig,
    // The observation was not added to the store because it is full. The
    // Observation itself is not too big to be added otherwise.
    kStoreFull,
    // The Observation was not added to the store because of an unspecified
    // writing error. It may be a file system error, or some other reason.
    kWriteFailed,
  };

  // StoreObservation takes a (possibly encrypted) observation, and its associated metadata and
  // stores it in the store.
  //
  // The three variants below represent storing a definitely encrypted observation
  // (EncyrptedMessage), storing a definitely unenrcypted message (Observation) and storing a
  // possibly encrypted message (StoredObservation).
  //
  // The first two are convenience methods that wrap around the third.

  StoreStatus StoreObservation(std::unique_ptr<EncryptedMessage> observation,
                               std::unique_ptr<ObservationMetadata> metadata) {
    auto obs = std::make_unique<StoredObservation>();
    obs->set_allocated_encrypted(observation.release());
    return StoreObservation(std::move(obs), std::move(metadata));
  }

  StoreStatus StoreObservation(std::unique_ptr<Observation> observation,
                               std::unique_ptr<ObservationMetadata> metadata) {
    auto obs = std::make_unique<StoredObservation>();
    obs->set_allocated_unencrypted(observation.release());
    return StoreObservation(std::move(obs), std::move(metadata));
  }

  virtual StoreStatus StoreObservation(std::unique_ptr<StoredObservation> observation,
                                       std::unique_ptr<ObservationMetadata> metadata) = 0;
};

// ObservationStore is an abstract interface to an underlying store of encrypted observations and
// their metadata. These are organized within the store into Envelopes. Individual (encrypted
// observation, metadata) pairs are added one-at-a-time via the method StoreObservation(). These
// pairs are pooled together and will eventually be combined into an Envelope. These Envelopes are
// then collected into a list, and will be returned one-at-a-time from calls to
// TakeNextEnvelopeHolder(). If there are no envelopes available to return, TakeNextEnvelopeHolder()
// will return nullptr.
//
// The EnvelopeHolders that are returned from this method should be treated as "owned" by the
// caller. When the EnvelopeHolder is destroyed, its underlying data is also deleted. If the
// underlying data should not be deleted (e.g. if the upload failed), the EnvelopeHolder should be
// placed back into the ObservationStore using the ReturnEnvelopeHolder() method.
class ObservationStore : public ObservationStoreWriterInterface {
 public:
  // EnvelopeHolder holds a reference to a single Envelope and its underlying
  // data storage. An instance of EnvelopeHolder is considered to own its
  // Envelope. When EnvelopeHolder is deleted, the underlying data storage for
  // the owned Envelope will be deleted. The ObservationStore considers the
  // envelopes owned by EnvelopeHolders to no longer be in the store.
  class EnvelopeHolder {
   public:
    EnvelopeHolder() = default;

    // When this EnvelopeHolder is deleted, the underlying data will be deleted.
    virtual ~EnvelopeHolder() = default;

    // MergeWith takes posession of the Envelope owned by |other| and merges
    // that EnvelopeHolder's underlying data with that of its own. After the
    // call completes, |other| no longer owns any Envelope and it is deleted
    // without deleting any underlying data.
    virtual void MergeWith(std::unique_ptr<EnvelopeHolder> other) = 0;

    // Returns a const reference to the Envelope owned by this EnvelopeHolder.  This is not
    // necessarily a cheap operation and may involve reading from disk or encrypting.
    //
    // |encrypter| Is used to encrypt observations that were not encrypted when they were added to
    // the store. It should not be null. (n.b. It is possible that observations were added to the
    // store with a different EncryptedMessageMaker, in this case, the envelope that is produced
    // will have observations encrypted with two (or more) different EncryptedMessageMakers.)
    //
    // TODO(fxb/3842): Make ObservationStore *only* store unencrypted observations.
    virtual const Envelope& GetEnvelope(util::EncryptedMessageMaker* encrypter) = 0;

    // Returns an estimated size on the wire of the resulting Envelope owned by
    // thes EnvelopeHolder.
    virtual size_t Size() = 0;

   private:
    EnvelopeHolder(const EnvelopeHolder&) = delete;
    EnvelopeHolder& operator=(const EnvelopeHolder&) = delete;
  };

  // max_bytes_per_observation. StoreObservation() will return kObservationTooBig if the given
  // encrypted Observation's serialized size is bigger than this.
  //
  // max_bytes_per_envelope. When pooling together observations into an Envelope, the
  // ObservationStore will try not to form envelopes larger than this size. This should be used to
  // avoid sending messages over HTTP that are too large.
  //
  // max_bytes_total. This is the maximum size of the Observations in the store.  If the size of the
  // accumulated Observation data reaches this value then ObservationStore will not accept any more
  // Observations: StoreObservation() will return kStoreFull, until enough observations are removed
  // from the store.
  //
  // REQUIRED:
  // 0 <= max_bytes_per_observation <= max_bytes_per_envelope <= max_bytes_total
  // 0 <= max_bytes_per_envelope
  explicit ObservationStore(size_t max_bytes_per_observation, size_t max_bytes_per_envelope,
                            size_t max_bytes_total);

  ~ObservationStore() override = default;

  // Returns a human-readable name for the StoreStatus.
  static std::string StatusDebugString(StoreStatus status);

  using ObservationStoreWriterInterface::StoreObservation;

  // Adds the given (StoredObservation, ObservationMetadata) pair into the store. If this causes the
  // pool of observations to exceed max_bytes_per_envelope, then the ObservationStore will construct
  // an EnvelopeHolder to be returned from TakeNextEnvelopeHolder().
  //
  // N.B. If the store has been disabled (IsDisabled() returns true) this method will always return
  // kOk, even though the observation has not been stored.
  StoreStatus StoreObservation(std::unique_ptr<StoredObservation> observation,
                               std::unique_ptr<ObservationMetadata> metadata) override = 0;

  // Returns the next EnvelopeHolder from the list of EnvelopeHolders in the
  // store. If there are no more EnvelopeHolders available, this will return
  // nullptr. A given EnvelopeHolder will only be returned from this function
  // *once* unless it is subsequently returned using ReturnEnvelopeHolder.
  virtual std::unique_ptr<EnvelopeHolder> TakeNextEnvelopeHolder() = 0;

  // ReturnEnvelopeHolder takes an EnvelopeHolder and adds it back to the store
  // so that it may be returned by a later call to TakeNextEnvelopeHolder(). Use
  // this when an envelope failed to upload, so the underlying data should not
  // be deleted.
  virtual void ReturnEnvelopeHolder(std::unique_ptr<EnvelopeHolder> envelope) = 0;

  // Resets the internal metrics to use the provided logger.
  virtual void ResetInternalMetrics(logger::LoggerInterface* internal_logger) = 0;

  [[nodiscard]] virtual const logger::InternalMetrics* internal_metrics() const = 0;

  // Returns true when the size of the data in the ObservationStore exceeds 60%
  // of max_bytes_total.
  [[nodiscard]] bool IsAlmostFull() const;

  // Returns an approximation of the size of all the data in the store.
  [[nodiscard]] virtual size_t Size() const = 0;

  // Returns wether or not the store is entirely empty.
  [[nodiscard]] virtual bool Empty() const = 0;

  // Returns the number of Observations that have been added to the
  // ObservationStore.
  [[nodiscard]] uint64_t num_observations_added() const;

  // Returns a vector containing the number of Observations that have been added
  // to the ObservationStore for each specified report.
  [[nodiscard]] std::vector<uint64_t> num_observations_added_for_reports(
      const std::vector<ReportSpec>& report_specs) const;

  // Resets the count of Observations that have been added to the
  // ObservationStore.
  void ResetObservationCounter();

  // Disable allows enabling/disabling the ObservationStore. When the store is disabled,
  // StoreObservation() will return kOk but the observation will not be stored.
  void Disable(bool is_disabled);

  // IsDisabled returns true if the ObservationStore is disabled and should ignore incoming
  // observations, by returning kOk and not storing the data.
  bool IsDisabled() { return is_disabled_; }

  // DeleteData removes all stored Observations from the device. After this method is called, a call
  // to Size() or TakeNextEnvelopeHolder() will return 0 and nullptr respectively.
  virtual void DeleteData() = 0;

 protected:
  // NOLINTNEXTLINE misc-non-private-member-variables-in-classes
  const size_t max_bytes_per_observation_;
  // NOLINTNEXTLINE misc-non-private-member-variables-in-classes
  const size_t max_bytes_per_envelope_;
  // NOLINTNEXTLINE misc-non-private-member-variables-in-classes
  const size_t max_bytes_total_;
  // NOLINTNEXTLINE misc-non-private-member-variables-in-classes
  const size_t almost_full_threshold_;
  // NOLINTNEXTLINE misc-non-private-member-variables-in-classes
  std::map<ReportSpec, uint64_t> num_obs_per_report_;

 private:
  bool is_disabled_ = false;
};

}  // namespace observation_store
}  // namespace cobalt

#endif  // COBALT_SRC_OBSERVATION_STORE_OBSERVATION_STORE_H_
