// Copyright 2019 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_STORAGE_LIB_BUFFER_RING_BUFFER_H_
#define SRC_STORAGE_LIB_BUFFER_RING_BUFFER_H_

#ifndef __Fuchsia__
#error Fuchsia-only Header
#endif

#include <lib/stdcompat/span.h>
#include <lib/zx/result.h>

#include <mutex>
#include <vector>

#include "src/storage/lib/buffer/block_buffer_view.h"
#include "src/storage/lib/buffer/vmo_buffer.h"
#include "src/storage/lib/operation/unbuffered_operation.h"

namespace storage {

class RingBufferReservation;

namespace internal {

// Internal state backing RingBuffer. Refer to that class for the public API.
//
// This class is not movable or copyable.
// This class is thread-safe.
class RingBufferState {
 public:
  explicit RingBufferState(VmoBuffer buffer)
      : buffer_(std::move(buffer)), reserved_start_(0), reserved_length_(0) {}
  RingBufferState(const RingBufferState&) = delete;
  RingBufferState& operator=(const RingBufferState&) = delete;
  RingBufferState(RingBufferState&& other) = delete;
  RingBufferState& operator=(RingBufferState&& other) = delete;
  ~RingBufferState() = default;

  // Reserves space for |blocks| contiguous blocks in the circular buffer.
  //
  // To perform optimally, these reservations should be destroyed in the same order
  // they are reserved.
  //
  // |blocks| must be greater than zero.
  // Returns ZX_ERR_NO_SPACE if there is not enough room.
  zx_status_t Reserve(uint64_t blocks, RingBufferReservation* out);

  // Returns the total amount of pending blocks which may be buffered.
  size_t capacity() const { return buffer_.capacity(); }

  uint32_t BlockSize() const { return buffer_.BlockSize(); }

  // Frees |reservation| from the buffer.
  //
  // Only callable by |RingBufferReservation|, since this frees the previously used
  // reservation.
  void Free(const RingBufferReservation& reservation);

  // Returns data starting at block |index| in the buffer.
  //
  // Only callable by |RingBufferReservation|, since this uses the previously created
  // reservation.
  void* Data(size_t index) { return buffer_.Data(index); }

  // Returns a pointer to the underlying buffer. Should only be accessible to the
  // |RingBufferReservation|, which should take caution to only reference reserved portions
  // of the buffer itself.
  VmoBuffer* buffer() { return &buffer_; }
  const VmoBuffer* buffer() const { return &buffer_; }

  // Returns the vmoid of the underlying RingBuffer.
  //
  // Only callable by |RingBufferReservation|, since this uses the previously created
  // reservation.
  vmoid_t vmoid() const { return buffer_.vmoid(); }

 private:
  struct Range {
    size_t start;
    size_t length;
  };

  // Returns true if there is space available for |blocks| blocks within the buffer.
  bool IsSpaceAvailableLocked(size_t blocks) const __TA_REQUIRES(lock_);

  // Actually frees |blocks| in the buffer at |start| in the buffer.
  void CompleteFreeLocked(size_t start, size_t blocks) __TA_REQUIRES(lock_);

  VmoBuffer buffer_;

  // Although this lock guards some fields of |RingBuffer| explicitly, access to the
  // buffer data ("who can access the region at [start, start + length)?") is implicit
  // via the RingBufferReservation objects.
  std::mutex lock_;

  // The units of all the following are "filesystem blocks".
  size_t reserved_start_ __TA_GUARDED(lock_) = 0;
  size_t reserved_length_ __TA_GUARDED(lock_) = 0;
  std::vector<Range> pending_free_ __TA_GUARDED(lock_);
};

}  // namespace internal

// A reservation of space within |RingBuffer|. Allows clients to safely access a portion
// of the circular buffer for either reading or writing.
//
// Releases the space when going out of scope (or reset).
//
// This class is movable, but not copyable.
// This class is thread-compatible.
class RingBufferReservation {
 public:
  RingBufferReservation() = default;

  // Creates a RingBufferReservation within a buffer, at |start| blocks within
  // the buffer, of |length| bytes long. [start, start + length) may wrap around the
  // RingBuffer.
  RingBufferReservation(internal::RingBufferState* buffer, size_t start, size_t length);
  RingBufferReservation(const RingBufferReservation&) = delete;
  RingBufferReservation& operator=(const RingBufferReservation&) = delete;
  RingBufferReservation(RingBufferReservation&& other);
  RingBufferReservation& operator=(RingBufferReservation&& other);
  virtual ~RingBufferReservation();

  // Copies from |in_requests|, at the provided |offset| into this reservation.
  //
  // Updates the in-memory offsets of |requests| so they point to the correct offsets in the
  // in-memory buffer instead of their original VMOs, outputting these updated requests.
  //
  // Returns an error if a VMO from |requests| cannot be accessed to write into
  // the buffer, but otherwise returns the number of blocks copied.
  //
  // Preconditions:
  // - The reservation must be large enough to copy |requests|:
  //  - offset + BlockCount(in_requests) <= length()
  // - |Reserved()| must be true.
  zx::result<uint64_t> CopyRequests(cpp20::span<const storage::UnbufferedOperation> in_operations,
                                    size_t offset,
                                    std::vector<storage::BufferedOperation>* out_operations);

  BlockBufferView buffer_view() { return view_; }

  // The first reservation block, relative to the start of |RingBuffer|.
  size_t start() const { return view_.start(); }

  // The total length of this reservation, in blocks.
  size_t length() const { return view_.length(); }

  // The capacity of the underlying buffer.
  size_t capacity() const { return buffer_->capacity(); }

  vmoid_t vmoid() const;

  // Returns one block of data starting at block |index| within this reservation.
  // Since this data has been reserved, |RingBuffer| will not attempt to access it concurrently.
  //
  // Preconditions:
  // - |Reserved()| must be true.
  // - |index| < |length()|
  void* Data(size_t index);
  const void* Data(size_t index) const;

 protected:
  // Returns true if the reservation holds blocks in a |RingBuffer|.
  bool Reserved() const { return buffer_ != nullptr; }

  // Unreserves the reservation. This will cause |Reserved()| to return
  // false for the duration of the |RingBufferReservation|'s lifetime.
  void Reset();

 private:
  internal::RingBufferState* buffer_ = nullptr;
  BlockBufferView view_;
};

// In-memory circular buffer.
//
// This class is not movable or copyable.
// This class is thread-safe.
class RingBuffer {
 public:
  explicit RingBuffer(VmoBuffer buffer) : state_(std::move(buffer)) {}
  RingBuffer(const RingBuffer&) = delete;
  RingBuffer& operator=(const RingBuffer&) = delete;
  RingBuffer(RingBuffer&& other) = delete;
  RingBuffer& operator=(RingBuffer&& other) = delete;
  ~RingBuffer() = default;

  // Initializes the buffer with |blocks| blocks of size |block_size|.
  static zx_status_t Create(VmoidRegistry* vmoid_registry, size_t blocks, uint32_t block_size,
                            const char* label, std::unique_ptr<RingBuffer>* out);

  // Reserves space for |blocks| contiguous blocks in the circular buffer.
  //
  // To perform optimally, these reservations should be destroyed in the same order
  // they are reserved.
  //
  // |blocks| must be greater than zero.
  // Returns ZX_ERR_NO_SPACE if there is not enough room.
  zx_status_t Reserve(uint64_t blocks, RingBufferReservation* out) {
    return state_.Reserve(blocks, out);
  }

  // Returns the total amount of pending blocks which may be buffered.
  size_t capacity() const { return state_.capacity(); }
  uint32_t BlockSize() const { return state_.buffer()->BlockSize(); }

 private:
  internal::RingBufferState state_;
};

// A utility class, holding a collection of write requests associated with a portion of a single
// RingBuffer, ready to be transmitted to persistent storage.
//
// This class is movable, but not copyable.
// This class is thread-safe.
class RingBufferRequests {
 public:
  RingBufferRequests() = default;
  RingBufferRequests(std::vector<storage::BufferedOperation> requests,
                     RingBufferReservation reservation);
  RingBufferRequests(const RingBufferRequests&) = delete;
  RingBufferRequests& operator=(const RingBufferRequests&) = delete;
  RingBufferRequests(RingBufferRequests&& other) = default;
  RingBufferRequests& operator=(RingBufferRequests&& other) = default;
  ~RingBufferRequests() = default;

  const std::vector<storage::BufferedOperation>& Operations() const { return requests_; }
  RingBufferReservation* Reservation() { return &reservation_; }

 private:
  std::vector<storage::BufferedOperation> requests_;
  RingBufferReservation reservation_;
};

}  // namespace storage

#endif  // SRC_STORAGE_LIB_BUFFER_RING_BUFFER_H_
