// 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 <algorithm>
#include <array>
#include <bit>
#include <cstddef>
#include <cstring>

#include "pw_bytes/endian.h"
#include "pw_bytes/span.h"
#include "pw_preprocessor/compiler.h"
#include "pw_status/status.h"
#include "pw_status/status_with_size.h"

namespace pw {

// ByteBuilder facilitates building bytes in a fixed-size buffer.
// BytesBuilders never overflow. Status is tracked for each operation and
// an overall status is maintained, which reflects the most recent error.
//
// A ByteBuilder does not own the buffer it writes to. It can be used to write
// bytes to any buffer. The ByteBuffer template class, defined below,
// allocates a buffer alongside a ByteBuilder.
class ByteBuilder {
 public:
  // iterator class will allow users of ByteBuilder and ByteBuffer to access
  // the data stored in the buffer. It has the functionality of C++'s
  // random access iterator.
  class iterator {
   public:
    using difference_type = ptrdiff_t;
    using value_type = std::byte;
    using pointer = std::byte*;
    using reference = std::byte&;
    using iterator_category = std::random_access_iterator_tag;

    explicit constexpr iterator(const std::byte* byte_ptr) : byte_(byte_ptr) {}

    constexpr iterator& operator++() {
      byte_ += 1;
      return *this;
    }

    constexpr iterator operator++(int) {
      iterator previous(byte_);
      operator++();
      return previous;
    }

    constexpr iterator& operator--() {
      byte_ -= 1;
      return *this;
    }

    constexpr iterator operator--(int) {
      iterator previous(byte_);
      operator--();
      return previous;
    }

    constexpr iterator operator+=(int n) {
      byte_ += n;
      return *this;
    }

    constexpr iterator operator+(int n) const { return iterator(byte_ + n); }

    constexpr iterator operator-=(int n) { return operator+=(-n); }

    constexpr iterator operator-(int n) const { return iterator(byte_ - n); }

    constexpr ptrdiff_t operator-(const iterator& rhs) const {
      return byte_ - rhs.byte_;
    }

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

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

    constexpr bool operator<(const iterator& rhs) const {
      return byte_ < rhs.byte_;
    }

    constexpr bool operator>(const iterator& rhs) const {
      return byte_ > rhs.byte_;
    }

    constexpr bool operator<=(const iterator& rhs) const {
      return !operator>(rhs);
    }

    constexpr bool operator>=(const iterator& rhs) const {
      return !operator<(rhs);
    }

    constexpr const std::byte& operator*() const { return *byte_; }

    constexpr const std::byte& operator[](int index) const {
      return byte_[index];
    }

    // The Peek methods will retreive ordered (Little/Big Endian) values
    // located at the iterator position without moving the iterator forward.
    int8_t PeekInt8() const { return static_cast<int8_t>(PeekUint8()); }

    uint8_t PeekUint8() const {
      return bytes::ReadInOrder<uint8_t>(std::endian::little, byte_);
    }

    int16_t PeekInt16(std::endian order = std::endian::little) const {
      return static_cast<int16_t>(PeekUint16(order));
    }

    uint16_t PeekUint16(std::endian order = std::endian::little) const {
      return bytes::ReadInOrder<uint16_t>(order, byte_);
    }

    int32_t PeekInt32(std::endian order = std::endian::little) const {
      return static_cast<int32_t>(PeekUint32(order));
    }

    uint32_t PeekUint32(std::endian order = std::endian::little) const {
      return bytes::ReadInOrder<uint32_t>(order, byte_);
    }

    int64_t PeekInt64(std::endian order = std::endian::little) const {
      return static_cast<int64_t>(PeekUint64(order));
    }

    uint64_t PeekUint64(std::endian order = std::endian::little) const {
      return bytes::ReadInOrder<uint64_t>(order, byte_);
    }

    // The Read methods will retreive ordered (Little/Big Endian) values
    // located at the iterator position and move the iterator forward by
    // sizeof(value) positions forward.
    int8_t ReadInt8() { return static_cast<int8_t>(ReadUint8()); }

    uint8_t ReadUint8() {
      uint8_t value = bytes::ReadInOrder<uint8_t>(std::endian::little, byte_);
      byte_ += 1;
      return value;
    }

    int16_t ReadInt16(std::endian order = std::endian::little) {
      return static_cast<int16_t>(ReadUint16(order));
    }

    uint16_t ReadUint16(std::endian order = std::endian::little) {
      uint16_t value = bytes::ReadInOrder<uint16_t>(order, byte_);
      byte_ += 2;
      return value;
    }

    int32_t ReadInt32(std::endian order = std::endian::little) {
      return static_cast<int32_t>(ReadUint32(order));
    }

    uint32_t ReadUint32(std::endian order = std::endian::little) {
      uint32_t value = bytes::ReadInOrder<uint32_t>(order, byte_);
      byte_ += 4;
      return value;
    }

    int64_t ReadInt64(std::endian order = std::endian::little) {
      return static_cast<int64_t>(ReadUint64(order));
    }

    uint64_t ReadUint64(std::endian order = std::endian::little) {
      int64_t value = bytes::ReadInOrder<int64_t>(order, byte_);
      byte_ += 8;
      return value;
    }

   private:
    const std::byte* byte_;
  };

  using element_type = const std::byte;
  using value_type = std::byte;
  using pointer = std::byte*;
  using reference = std::byte&;
  using iterator = iterator;
  using const_iterator = iterator;

  // Creates an empty ByteBuilder.
  constexpr ByteBuilder(ByteSpan buffer) : buffer_(buffer), size_(0) {}

  // Disallow copy/assign to avoid confusion about where the bytes is actually
  // stored. ByteBuffers may be copied into one another.
  ByteBuilder(const ByteBuilder&) = delete;

  ByteBuilder& operator=(const ByteBuilder&) = delete;

  // Returns the contents of the bytes buffer. Always null-terminated.
  const std::byte* data() const { return buffer_.data(); }

  // Returns the ByteBuilder's status, which reflects the most recent error
  // that occurred while updating the bytes. After an update fails, the status
  // remains non-OK until it is cleared with clear() or clear_status(). Returns:
  //
  //     OK if no errors have occurred
  //     RESOURCE_EXHAUSTED if output to the ByteBuilder was truncated
  //     INVALID_ARGUMENT if printf-style formatting failed
  //     OUT_OF_RANGE if an operation outside the buffer was attempted
  //
  Status status() const { return status_; }

  // Returns status() and size() as a StatusWithSize.
  StatusWithSize status_with_size() const {
    return StatusWithSize(status_, size_);
  }

  // True if status() is Status::Ok().
  bool ok() const { return status_.ok(); }

  // True if the bytes builder is empty.
  bool empty() const { return size() == 0u; }

  // Returns the current length of the bytes.
  size_t size() const { return size_; }

  // Returns the maximum length of the bytes.
  size_t max_size() const { return buffer_.size(); }

  // Clears the bytes and resets its error state.
  void clear() {
    size_ = 0;
    status_ = Status::Ok();
  };

  // Sets the statuses to Status::Ok();
  void clear_status() { status_ = Status::Ok(); }

  // Appends a single byte. Sets the status to RESOURCE_EXHAUSTED if the
  // byte cannot be added because the buffer is full.
  void push_back(std::byte b) { append(1, b); }

  // Removes the last byte. Sets the status to OUT_OF_RANGE if the buffer
  // is empty (in which case the unsigned overflow is intentional).
  void pop_back() PW_NO_SANITIZE("unsigned-integer-overflow") {
    resize(size() - 1);
  }

  // Root of bytebuffer wrapped in iterator type
  const_iterator begin() const { return iterator(data()); }
  const_iterator cbegin() const { return begin(); }

  // End of bytebuffer wrapped in iterator type
  const_iterator end() const { return iterator(data() + size()); }
  const_iterator cend() const { return end(); }

  // Front and Back C++ container functions
  const std::byte& front() const { return buffer_[0]; }
  const std::byte& back() const { return buffer_[size() - 1]; }

  // Appends the provided byte count times.
  ByteBuilder& append(size_t count, std::byte b);

  // Appends count bytes from 'bytes' to the end of the ByteBuilder. If count
  // exceeds the remaining space in the ByteBuffer, no bytes will be appended
  // and the status is set to RESOURCE_EXHAUSTED.
  ByteBuilder& append(const void* bytes, size_t count);

  // Appends bytes from a byte span that calls the pointer/length version.
  ByteBuilder& append(ConstByteSpan bytes) {
    return append(bytes.data(), bytes.size());
  }

  // Sets the ByteBuilder's size. This function only truncates; if
  // new_size > size(), it sets status to OUT_OF_RANGE and does nothing.
  void resize(size_t new_size);

  // Put methods for inserting different 8-bit ints
  ByteBuilder& PutUint8(uint8_t val) { return WriteInOrder(val); }

  ByteBuilder& PutInt8(int8_t val) { return WriteInOrder(val); }

  // Put methods for inserting different 16-bit ints
  ByteBuilder& PutUint16(uint16_t value,
                         std::endian order = std::endian::little) {
    return WriteInOrder(bytes::ConvertOrderTo(order, value));
  }

  ByteBuilder& PutInt16(int16_t value,
                        std::endian order = std::endian::little) {
    return PutUint16(static_cast<uint16_t>(value), order);
  }

  // Put methods for inserting different 32-bit ints
  ByteBuilder& PutUint32(uint32_t value,
                         std::endian order = std::endian::little) {
    return WriteInOrder(bytes::ConvertOrderTo(order, value));
  }

  ByteBuilder& PutInt32(int32_t value,
                        std::endian order = std::endian::little) {
    return PutUint32(static_cast<uint32_t>(value), order);
  }

  // Put methods for inserting different 64-bit ints
  ByteBuilder& PutUint64(uint64_t value,
                         std::endian order = std::endian::little) {
    return WriteInOrder(bytes::ConvertOrderTo(order, value));
  }

  ByteBuilder& PutInt64(int64_t value,
                        std::endian order = std::endian::little) {
    return PutUint64(static_cast<uint64_t>(value), order);
  }

 protected:
  // Functions to support ByteBuffer copies.
  constexpr ByteBuilder(const ByteSpan& buffer, const ByteBuilder& other)
      : buffer_(buffer), size_(other.size_), status_(other.status_) {}

  void CopySizeAndStatus(const ByteBuilder& other) {
    size_ = other.size_;
    status_ = other.status_;
  };

 private:
  template <typename T>
  ByteBuilder& WriteInOrder(T value) {
    return append(&value, sizeof(value));
  }
  size_t ResizeForAppend(size_t bytes_to_append);

  const ByteSpan buffer_;

  size_t size_;
  Status status_;
};

// ByteBuffers declare a buffer along with a ByteBuilder.
template <size_t size_bytes>
class ByteBuffer : public ByteBuilder {
 public:
  ByteBuffer() : ByteBuilder(buffer_) {}

  // ByteBuffers of the same size may be copied and assigned into one another.
  ByteBuffer(const ByteBuffer& other) : ByteBuilder(buffer_, other) {
    CopyContents(other);
  }

  // A smaller ByteBuffer may be copied or assigned into a larger one.
  template <size_t other_size_bytes>
  ByteBuffer(const ByteBuffer<other_size_bytes>& other)
      : ByteBuilder(buffer_, other) {
    static_assert(ByteBuffer<other_size_bytes>::max_size() <= max_size(),
                  "A ByteBuffer cannot be copied into a smaller buffer");
    CopyContents(other);
  }

  template <size_t other_size_bytes>
  ByteBuffer& operator=(const ByteBuffer<other_size_bytes>& other) {
    assign<other_size_bytes>(other);
    return *this;
  }

  ByteBuffer& operator=(const ByteBuffer& other) {
    assign<size_bytes>(other);
    return *this;
  }

  template <size_t other_size_bytes>
  ByteBuffer& assign(const ByteBuffer<other_size_bytes>& other) {
    static_assert(ByteBuffer<other_size_bytes>::max_size() <= max_size(),
                  "A ByteBuffer cannot be copied into a smaller buffer");
    CopySizeAndStatus(other);
    CopyContents(other);
    return *this;
  }

  // Returns the maximum length of the bytes that can be inserted in the bytes
  // buffer.
  static constexpr size_t max_size() { return size_bytes; }

  // Returns a ByteBuffer<size_bytes>& instead of a generic ByteBuilder& for
  // append calls.
  template <typename... Args>
  ByteBuffer& append(Args&&... args) {
    ByteBuilder::append(std::forward<Args>(args)...);
    return *this;
  }

 private:
  template <size_t kOtherSize>
  void CopyContents(const ByteBuffer<kOtherSize>& other) {
    std::memcpy(buffer_.data(), other.data(), other.size());
  }

  std::array<std::byte, size_bytes> buffer_;
};

}  // namespace pw
