// Copyright 2020 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#pragma once

#include <cstddef>
#include <span>

#include "pw_containers/intrusive_list.h"
#include "pw_result/result.h"
#include "pw_status/status.h"

namespace pw {
namespace ring_buffer {

// A circular ring buffer for arbitrary length data entries. Each PushBack()
// produces a buffer entry. Each entry consists of a preamble followed by an
// arbitrary length data chunk. The preamble is comprised of an optional user
// preamble byte and an always present varint. The varint encodes the number of
// bytes in the data chunk. This is a FIFO queue, with the oldest entries at
// the 'front' (to be processed by readers) and the newest entries at the 'back'
// (where the writer pushes to).
//
// The ring buffer supports multiple readers, which can be attached/detached
// from the buffer. Each reader has its own read pointer and can peek and pop
// the entry at the head. Entries are not bumped out from the buffer until all
// readers have moved past that entry, or if the buffer is at capacity and space
// is needed to push a new entry. When making space, the buffer will push slow
// readers forward to the new oldest entry. Entries are internally wrapped
// around as needed.
class PrefixedEntryRingBufferMulti {
 public:
  typedef Status (*ReadOutput)(std::span<const std::byte>);

  // A reader that provides a single-reader interface into the multi-reader ring
  // buffer it has been attached to via AttachReader(). Readers maintain their
  // read position in the ring buffer as well as the remaining count of entries
  // from that position.
  //
  // If no readers are currently attached, the reader starts at the current
  // write head. If readers are currently attached, the reader is set to the
  // location and entry count of the slowest reader in the set.
  //
  // Readers can peek and pop entries similar to the single-reader interface.
  // When popping entries, although the reader moves forward and drops the
  // entry, the entry is not removed from the ring buffer until all other
  // attached readers have moved past that entry.
  //
  // When the attached ring buffer needs to make space, it may push the reader
  // index forward. Users of this class should consider the possibility of data
  // loss if they read slower than the writer.
  class Reader : public IntrusiveList<Reader>::Item {
   public:
    constexpr Reader() : buffer_(nullptr), read_idx_(0), entry_count_(0) {}

    // TODO(pwbug/344): Add locking to the internal functions. Who owns the
    // lock? This class? Does this class need a lock if it's not a multi-reader?
    // (One doesn't exist today but presumably nothing prevents push + pop
    // operations from happening on two different threads).

    // Read the oldest stored data chunk of data from the ring buffer to
    // the provided destination std::span. The number of bytes read is written
    // to bytes_read
    //
    // Precondition: the buffer data must not be corrupt, otherwise there will
    // be a crash.
    //
    // Return values:
    // OK - Data successfully read from the ring buffer.
    // FAILED_PRECONDITION - Buffer not initialized.
    // OUT_OF_RANGE - No entries in ring buffer to read.
    // RESOURCE_EXHAUSTED - Destination data std::span was smaller number of
    // bytes than the data size of the data chunk being read.  Available
    // destination bytes were filled, remaining bytes of the data chunk were
    // ignored.
    Status PeekFront(std::span<std::byte> data, size_t* bytes_read_out) const {
      return buffer_->InternalPeekFront(*this, data, bytes_read_out);
    }

    Status PeekFront(ReadOutput output) const {
      return buffer_->InternalPeekFront(*this, output);
    }

    // Peek the front entry's preamble only to avoid copying data unnecessarily.
    //
    // Precondition: the buffer data must not be corrupt, otherwise there will
    // be a crash.
    Status PeekFrontPreamble(uint32_t& user_preamble_out) const {
      return buffer_->InternalPeekFrontPreamble(*this, user_preamble_out);
    }

    // Same as PeekFront but includes the entry's preamble of optional user
    // value and the varint of the data size.
    // TODO(pwbug/341): Move all other APIs to passing bytes_read by reference,
    // as it is required to determine the length populated in the span.
    Status PeekFrontWithPreamble(std::span<std::byte> data,
                                 uint32_t& user_preamble_out,
                                 size_t& entry_bytes_read_out) const;

    Status PeekFrontWithPreamble(std::span<std::byte> data,
                                 size_t* bytes_read_out) const {
      return buffer_->InternalPeekFrontWithPreamble(
          *this, data, bytes_read_out);
    }

    Status PeekFrontWithPreamble(ReadOutput output) const {
      return buffer_->InternalPeekFrontWithPreamble(*this, output);
    }

    // Pop and discard the oldest stored data chunk of data from the ring
    // buffer.
    //
    // Precondition: the buffer data must not be corrupt, otherwise there will
    // be a crash.
    //
    // Return values:
    // OK - Data successfully read from the ring buffer.
    // FAILED_PRECONDITION - Buffer not initialized.
    // OUT_OF_RANGE - No entries in ring buffer to pop.
    Status PopFront() { return buffer_->InternalPopFront(*this); }

    // Get the size in bytes of the next chunk, not including preamble, to be
    // read.
    //
    // Precondition: the buffer data must not be corrupt, otherwise there will
    // be a crash.
    size_t FrontEntryDataSizeBytes() const {
      return buffer_->InternalFrontEntryDataSizeBytes(*this);
    }

    // Get the size in bytes of the next chunk, including preamble and data
    // chunk, to be read.
    //
    // Precondition: the buffer data must not be corrupt, otherwise there will
    // be a crash.
    size_t FrontEntryTotalSizeBytes() const {
      return buffer_->InternalFrontEntryTotalSizeBytes(*this);
    }

    // Get the number of variable-length entries currently in the ring buffer.
    //
    // Return value:
    // Entry count.
    size_t EntryCount() const { return entry_count_; }

   private:
    friend PrefixedEntryRingBufferMulti;

    // Internal constructors for the iterator class to create Reader instances
    // at specific positions. Readers constructed through this interface cannot
    // be attached/detached from the multisink.
    constexpr Reader(Reader& reader)
        : Reader(reader.buffer_, reader.read_idx_, reader.entry_count_) {}
    constexpr Reader(PrefixedEntryRingBufferMulti* buffer,
                     size_t read_idx,
                     size_t entry_count)
        : buffer_(buffer), read_idx_(read_idx), entry_count_(entry_count) {}

    PrefixedEntryRingBufferMulti* buffer_;
    size_t read_idx_;
    size_t entry_count_;
  };

  // An entry returned by the iterator containing the byte span of the entry
  // and preamble data (if the ring buffer was configured with a preamble).
  struct Entry {
    std::span<const std::byte> buffer;
    uint32_t preamble;
  };

  // An iterator that can be used to walk through all entries from a given
  // Reader position, without mutating the underlying buffer. This is useful in
  // crash contexts where all available entries in the buffer must be acquired,
  // even those that have already been consumed by all attached readers.
  class iterator {
   public:
    iterator() : ring_buffer_(nullptr), read_idx_(0), entry_count_(0) {}
    iterator(Reader& reader)
        : ring_buffer_(reader.buffer_),
          read_idx_(0),
          entry_count_(reader.entry_count_) {
      Status dering_result = ring_buffer_->InternalDering(reader);
      PW_DASSERT(dering_result.ok());
    }

    iterator& operator++();
    iterator operator++(int) {
      iterator original = *this;
      ++*this;
      return original;
    }

    // Returns entry at current position.
    const Entry& operator*() const;
    const Entry* operator->() const { return &operator*(); }

    constexpr bool operator==(const iterator& rhs) const {
      return entry_count_ == rhs.entry_count_;
    }

    constexpr bool operator!=(const iterator& rhs) const {
      return entry_count_ != rhs.entry_count_;
    }

    // Returns the status of the last iteration operation. If the iterator
    // fails to read an entry, it will move to iterator::end() and indicate
    // the failure reason here.
    Status status() const { return iteration_status_; }

   private:
    static constexpr Entry kEndEntry = {
        .buffer = std::span<const std::byte>(),
        .preamble = 0,
    };

    void SkipToEnd(Status status) {
      iteration_status_ = status;
      entry_ = kEndEntry;
      entry_count_ = 0;
    }

    PrefixedEntryRingBufferMulti* ring_buffer_;
    size_t read_idx_;
    size_t entry_count_;

    mutable Entry entry_;
    Status iteration_status_;
  };

  using element_type = const Entry;
  using value_type = std::remove_cv_t<const Entry>;
  using pointer = const Entry;
  using reference = const Entry&;
  using const_iterator = iterator;  // Standard alias for iterable types.

  iterator begin() { return iterator(GetSlowestReaderWritable()); }
  iterator end() { return iterator(); }
  const_iterator cbegin() { return begin(); }
  const_iterator cend() { return end(); }

  // TODO(pwbug/340): Consider changing bool to an enum, to explicitly enumerate
  // what this variable means in clients.
  PrefixedEntryRingBufferMulti(bool user_preamble = false)
      : buffer_(nullptr),
        buffer_bytes_(0),
        write_idx_(0),
        user_preamble_(user_preamble) {}

  // Set the raw buffer to be used by the ring buffer.
  //
  // Return values:
  // OK - successfully set the raw buffer.
  // INVALID_ARGUMENT - Argument was nullptr, size zero, or too large.
  Status SetBuffer(std::span<std::byte> buffer);

  // Determines if the ring buffer has corrupted entries.
  //
  // Precondition: At least one reader must be attached to the ring buffer.
  // Return values:
  // OK - No corruption was detected.
  // DATA_LOSS - Corruption was detected.
  Status CheckForCorruption() {
    iterator it = begin();
    for (; it != end(); ++it) {
    }
    return it.status();
  }

  // Attach reader to the ring buffer. Readers can only be attached to one
  // ring buffer at a time.
  //
  // Return values:
  // OK - Successfully configured reader for ring buffer.
  // INVALID_ARGUMENT - Argument was already attached to another ring buffer.
  Status AttachReader(Reader& reader);

  // Detach reader from the ring buffer. Readers can only be detached if they
  // were previously attached.
  //
  // Return values:
  // OK - Successfully removed reader for ring buffer.
  // INVALID_ARGUMENT - Argument was not previously attached to this ring
  // buffer.
  Status DetachReader(Reader& reader);

  // Removes all data from the ring buffer.
  void Clear();

  // Write a chunk of data to the ring buffer. If available space is less than
  // size of data chunk to be written then silently pop and discard oldest
  // stored data chunks until space is available.
  //
  // Preamble argument is a caller-provided value prepended to the front of the
  // entry. It is only used if user_preamble was set at class construction
  // time. It is varint-encoded before insertion into the buffer.
  //
  // Return values:
  // OK - Data successfully written to the ring buffer.
  // FAILED_PRECONDITION - Buffer not initialized.
  // OUT_OF_RANGE - Size of data is greater than buffer size.
  Status PushBack(std::span<const std::byte> data,
                  uint32_t user_preamble_data = 0) {
    return InternalPushBack(data, user_preamble_data, true);
  }

  // [Deprecated] An implementation of PushBack that accepts a single-byte as
  // preamble data. Clients should migrate to passing uint32_t preamble data.
  Status PushBack(std::span<const std::byte> data,
                  std::byte user_preamble_data) {
    return PushBack(data, static_cast<uint32_t>(user_preamble_data));
  }

  // Write a chunk of data to the ring buffer if there is space available.
  //
  // Preamble argument is a caller-provided value prepended to the front of the
  // entry. It is only used if user_preamble was set at class construction
  // time. It is varint-encoded before insertion into the buffer.
  //
  // Precondition: the buffer data must not be corrupt, otherwise there will
  // be a crash.
  //
  // Return values:
  // OK - Data successfully written to the ring buffer.
  // INVALID_ARGUMENT - Size of data to write is zero bytes
  // FAILED_PRECONDITION - Buffer not initialized.
  // OUT_OF_RANGE - Size of data is greater than buffer size.
  // RESOURCE_EXHAUSTED - The ring buffer doesn't have space for the data
  // without popping off existing elements.
  Status TryPushBack(std::span<const std::byte> data,
                     uint32_t user_preamble_data = 0) {
    return InternalPushBack(data, user_preamble_data, false);
  }

  // [Deprecated] An implementation of TryPushBack that accepts a single-byte as
  // preamble data. Clients should migrate to passing uint32_t preamble data.
  Status TryPushBack(std::span<const std::byte> data,
                     std::byte user_preamble_data) {
    return TryPushBack(data, static_cast<uint32_t>(user_preamble_data));
  }

  // Get the size in bytes of all the current entries in the ring buffer,
  // including preamble and data chunk.
  size_t TotalUsedBytes() const { return buffer_bytes_ - RawAvailableBytes(); }

  // Dering the buffer by reordering entries internally in the buffer by
  // rotating to have the oldest entry is at the lowest address/index with
  // newest entry at the highest address. If no readers are attached, the buffer
  // is deringed at the current write index.
  //
  // Return values:
  // OK - Buffer data successfully deringed.
  // FAILED_PRECONDITION - Buffer not initialized.
  Status Dering();

 private:
  // Read the oldest stored data chunk of data from the ring buffer to
  // the provided destination std::span. The number of bytes read is written to
  // `bytes_read_out`.
  //
  // Precondition: the buffer data must not be corrupt, otherwise there will
  // be a crash.
  //
  // Return values:
  // OK - Data successfully read from the ring buffer.
  // FAILED_PRECONDITION - Buffer not initialized.
  // OUT_OF_RANGE - No entries in ring buffer to read.
  // RESOURCE_EXHAUSTED - Destination data std::span was smaller number of bytes
  // than the data size of the data chunk being read.  Available destination
  // bytes were filled, remaining bytes of the data chunk were ignored.
  Status InternalPeekFront(const Reader& reader,
                           std::span<std::byte> data,
                           size_t* bytes_read_out) const;
  Status InternalPeekFront(const Reader& reader, ReadOutput output) const;

  Status InternalPeekFrontPreamble(const Reader& reader,
                                   uint32_t& user_preamble_out) const;
  // Same as Read but includes the entry's preamble of optional user value and
  // the varint of the data size
  Status InternalPeekFrontWithPreamble(const Reader& reader,
                                       std::span<std::byte> data,
                                       size_t* bytes_read_out) const;
  Status InternalPeekFrontWithPreamble(const Reader& reader,
                                       ReadOutput output) const;

  // Pop and discard the oldest stored data chunk of data from the ring buffer.
  //
  // Precondition: the buffer data must not be corrupt, otherwise there will
  // be a crash.
  //
  // Return values:
  // OK - Data successfully read from the ring buffer.
  // FAILED_PRECONDITION - Buffer not initialized.
  // OUT_OF_RANGE - No entries in ring buffer to pop.
  Status InternalPopFront(Reader& reader);

  // Get the size in bytes of the next chunk, not including preamble, to be
  // read.
  size_t InternalFrontEntryDataSizeBytes(const Reader& reader) const;

  // Get the size in bytes of the next chunk, including preamble and data
  // chunk, to be read.
  size_t InternalFrontEntryTotalSizeBytes(const Reader& reader) const;

  // Internal version of Read used by all the public interface versions. T
  // should be of type ReadOutput.
  template <typename T>
  Status InternalRead(const Reader& reader,
                      T read_output,
                      bool include_preamble_in_output,
                      uint32_t* user_preamble_out = nullptr) const;

  // Dering the buffer by reordering entries internally in the buffer by
  // rotating to have the oldest entry is at the lowest address/index with
  // newest entry at the highest address. If no readers are attached, the buffer
  // is deringed at the current write index.
  //
  // Return values:
  // OK - Buffer data successfully deringed.
  // FAILED_PRECONDITION - Buffer not initialized.
  Status InternalDering(Reader& reader);

  struct EntryInfo {
    size_t preamble_bytes;
    uint32_t user_preamble;
    size_t data_bytes;
  };

  // Push back implementation, which optionally discards front elements to fit
  // the incoming element.
  Status InternalPushBack(std::span<const std::byte> data,
                          uint32_t user_preamble_data,
                          bool pop_front_if_needed);

  // Internal function to pop all of the slowest readers. This function may pop
  // multiple readers if multiple are slow.
  //
  // Precondition: This function requires that at least one reader is attached
  // and has at least one entry to pop. There will be a crash if data is
  // corrupted.
  void InternalPopFrontAll();

  // Returns a the slowest reader in the list.
  //
  // Precondition: This function requires that at least one reader is attached.
  const Reader& GetSlowestReader() const;
  Reader& GetSlowestReaderWritable() {
    return const_cast<Reader&>(GetSlowestReader());
  }

  // Get info struct with the size of the preamble and data chunk for the next
  // entry to be read. Calls RawFrontEntryInfo and asserts on failure.
  //
  // Precondition: the buffer data must not be corrupt, otherwise there will
  // be a crash.
  EntryInfo FrontEntryInfo(const Reader& reader) const;

  // Get info struct with the size of the preamble and data chunk for the next
  // entry to be read.
  //
  // Returns:
  // OK - EntryInfo containing the next entry metadata.
  // DATA_LOSS - Failed to read the metadata at this location.
  Result<EntryInfo> RawFrontEntryInfo(size_t source_idx) const;

  // Get the raw number of available bytes free in the ring buffer. This is
  // not available bytes for data, since there is a variable size preamble for
  // each entry.
  size_t RawAvailableBytes() const;

  // Do the basic write of the specified number of bytes starting at the last
  // write index of the ring buffer to the destination, handing any wrap-around
  // of the ring buffer. This is basic, raw operation with no safety checks.
  void RawWrite(std::span<const std::byte> source);

  // Do the basic read of the specified number of bytes starting at the given
  // index of the ring buffer to the destination, handing any wrap-around of
  // the ring buffer. This is basic, raw operation with no safety checks.
  void RawRead(std::byte* destination,
               size_t source_idx,
               size_t length_bytes) const;

  size_t IncrementIndex(size_t index, size_t count) const;

  std::byte* buffer_;
  size_t buffer_bytes_;

  size_t write_idx_;
  const bool user_preamble_;

  // List of attached readers.
  IntrusiveList<Reader> readers_;

  // Maximum bufer size allowed. Restricted to this to allow index aliasing to
  // not overflow.
  static constexpr size_t kMaxBufferBytes =
      std::numeric_limits<size_t>::max() / 2;
};

class PrefixedEntryRingBuffer : public PrefixedEntryRingBufferMulti,
                                public PrefixedEntryRingBufferMulti::Reader {
 public:
  PrefixedEntryRingBuffer(bool user_preamble = false)
      : PrefixedEntryRingBufferMulti(user_preamble) {
    AttachReader(*this)
        .IgnoreError();  // TODO(pwbug/387): Handle Status properly
  }
};

}  // namespace ring_buffer
}  // namespace pw
