// 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 "pw_containers/intrusive_list.h"
#include "pw_result/result.h"
#include "pw_span/span.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)(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(b/235351035): 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 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 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(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(b/235351847): Move all other APIs to passing bytes_read by
    // reference, as it is required to determine the length populated in the
    // span.
    Status PeekFrontWithPreamble(span<std::byte> data,
                                 uint32_t& user_preamble_out,
                                 size_t& entry_bytes_read_out) const;

    Status PeekFrontWithPreamble(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 {
    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 = 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(b/235351861): 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(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(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(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(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(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(); }

  // Returns total size of ring buffer in bytes.
  size_t TotalSizeBytes() const { return buffer_bytes_; }

  // 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 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 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,
                           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,
                                       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(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(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(b/242598609): Handle Status properly
  }
};

}  // namespace ring_buffer
}  // namespace pw
