// 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_ENCODER_OBSERVATION_STORE_H_
#define COBALT_ENCODER_OBSERVATION_STORE_H_

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

#include "./envelope.pb.h"
#include "./observation.pb.h"
#include "./observation_batch.pb.h"

namespace cobalt {
namespace encoder {

// 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 {
    // AddEncryptedObservation() 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,
  };

  virtual StoreStatus AddEncryptedObservation(
      std::unique_ptr<EncryptedMessage> message,
      std::unique_ptr<ObservationMetadata> metadata) = 0;

  // Returns the number of Observations that have been added to the
  // ObservationStore.
  virtual size_t num_observations_added() = 0;

  // Resets the count of Observations that have been added to the
  // ObservationStore.
  virtual void ResetObservationCounter() = 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 AddEncryptedObservation(). 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() {}

    // When this EnvelopeHolder is deleted, the underlying data will be deleted.
    virtual ~EnvelopeHolder() {}

    // 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.
    virtual const Envelope& GetEnvelope() = 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. AddEncryptedObservation() 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 gRPC or 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:
  // AddEncryptedObservation() 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);

  virtual ~ObservationStore() {}

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

  // Adds the given (encrypted observation, metadata) 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().
  virtual StoreStatus AddEncryptedObservation(
      std::unique_ptr<EncryptedMessage> message,
      std::unique_ptr<ObservationMetadata> metadata) = 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;

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

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

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

 protected:
  const size_t max_bytes_per_observation_;
  const size_t max_bytes_per_envelope_;
  const size_t max_bytes_total_;
  const size_t almost_full_threshold_;
};

}  // namespace encoder
}  // namespace cobalt

#endif  // COBALT_ENCODER_OBSERVATION_STORE_H_
