#ifndef AOS_RING_BUFFER_H_
#define AOS_RING_BUFFER_H_

#include <array>
#include <cstddef>
#include <iterator>
#include <new>
#include <type_traits>

namespace aos {

// This is a helper to keep track of some amount of recent data. As you push
// data into the ring buffer, it gets stored. If the buffer becomes full, it
// will start overwriting the oldest data.
template <typename Data, size_t buffer_size>
class RingBuffer {
  template <typename ValueType, typename BufferType>
  struct generic_iterator {
    using iterator_category = ::std::random_access_iterator_tag;
    using value_type = ValueType;
    using difference_type = ::std::ptrdiff_t;
    using pointer = value_type *;
    using reference = value_type &;

    explicit generic_iterator(BufferType *buffer, size_t index)
        : buffer_(buffer), index_(index) {}

    generic_iterator &operator++() {
      ++index_;
      return *this;
    }
    generic_iterator operator++(int) {
      const generic_iterator retval = *this;
      ++(*this);
      return retval;
    }
    generic_iterator &operator--() {
      --index_;
      return *this;
    }
    generic_iterator operator--(int) {
      const generic_iterator retval = *this;
      --(*this);
      return retval;
    }

    generic_iterator &operator+=(ptrdiff_t i) {
      index_ += i;
      return *this;
    }
    generic_iterator operator+(ptrdiff_t i) const {
      generic_iterator retval = *this;
      retval += i;
      return retval;
    }
    generic_iterator &operator-=(ptrdiff_t i) {
      index_ -= i;
      return *this;
    }
    generic_iterator operator-(ptrdiff_t i) const {
      generic_iterator retval = *this;
      retval -= i;
      return retval;
    }

    ptrdiff_t operator-(generic_iterator other) const {
      return index_ - other.index_;
    }

    bool operator==(generic_iterator other) const {
      return buffer_ == other.buffer_ && index_ == other.index_;
    }
    bool operator!=(generic_iterator other) const { return !(*this == other); }

    bool operator<(generic_iterator other) const {
      return buffer_ == other.buffer_ && index_ < other.index_;
    }
    bool operator>(generic_iterator other) const {
      return buffer_ == other.buffer_ && index_ > other.index_;
    }
    bool operator<=(generic_iterator other) const {
      return buffer_ == other.buffer_ && index_ <= other.index_;
    }
    bool operator>=(generic_iterator other) const {
      return buffer_ == other.buffer_ && index_ >= other.index_;
    }

    reference operator*() const { return (*buffer_)[index_]; }
    pointer operator->() const { return &(*buffer_)[index_]; }

    reference operator[](difference_type i) const {
      return (*buffer_)[index_ + i];
    }

   private:
    BufferType *buffer_;
    size_t index_;
  };

 public:
  using iterator = generic_iterator<Data, RingBuffer>;
  using const_iterator = generic_iterator<const Data, const RingBuffer>;

  static constexpr size_t kBufferSize = buffer_size;

  constexpr RingBuffer() {}
  ~RingBuffer() { Reset(); }

  // Add an item to the RingBuffer, overwriting the oldest element if necessary.
  //
  // Invalidates the end iterator.
  void Push(Data data) {
    if (full()) {
      (*this)[0] = std::move(data);
      oldest_ = (oldest_ + 1) % buffer_size;
    } else {
      new (&(*this)[size_]) Data(std::move(data));
      ++size_;
    }
  }

  // Removes the oldest element.
  //
  // Invalidates all iterators.
  void Shift() {
    (*this)[0].~Data();
    oldest_ = (oldest_ + 1) % buffer_size;
    --size_;
  }

  // Return the value of the index requested, adjusted so that the RingBuffer
  // contains the oldest element first and the newest last.
  Data &operator[](size_t index) {
#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
    return *std::launder(
        reinterpret_cast<Data *>(&data_[(oldest_ + index) % buffer_size]));
#else
    // TODO(brian): Remove this when all our compilers are 17 or newer.
    return *reinterpret_cast<Data *>(&data_[(oldest_ + index) % buffer_size]);
#endif
  }

  const Data &operator[](size_t index) const {
#if defined(__cpp_lib_launder) && __cpp_lib_launder >= 201606
    return *std::launder(reinterpret_cast<const Data *>(
        &data_[(oldest_ + index) % buffer_size]));
#else
    // TODO(brian): Remove this when all our compilers are 17 or newer.
    return *reinterpret_cast<const Data *>(
        &data_[(oldest_ + index) % buffer_size]);
#endif
  }

  // Returns the capacity of the RingBuffer
  size_t capacity() const { return buffer_size; }

  // Returns the number of elements stored in the RingBuffer
  size_t size() const { return size_; }

  // Is the RingBuffer empty or full?
  bool empty() const { return size_ == 0; }

  bool full() const { return size_ == buffer_size; }

  // Clears all the data out of the buffer.
  //
  // Invalidates all iterators.
  void Reset() {
    while (!empty()) {
      Shift();
    }
  }

  iterator begin() { return iterator(this, 0); }
  iterator end() { return iterator(this, size()); }

  const_iterator begin() const { return const_iterator(this, 0); }
  const_iterator end() const { return const_iterator(this, size()); }

 private:
  using DataStorage =
      typename std::aligned_storage<sizeof(Data), alignof(Data)>::type;
  std::array<DataStorage, buffer_size> data_;

  // Oldest contains the oldest item added to the RingBuffer which will be
  // the next one to be overwritten
  size_t oldest_ = 0;
  size_t size_ = 0;
};

}  // namespace aos

#endif  // AOS_RING_BUFFER_H_
