// 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
    //
    // 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);
    }

    // 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.
    //
    // 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.
    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.
    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.
  //
  // 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`.
  //
  // 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;

  // 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.
  //
  // 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.
  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.
  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.
  // DataLoss - 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
