// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_COMMON_BYTE_BUFFER_H_
#define SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_COMMON_BYTE_BUFFER_H_

#include <zircon/assert.h>
#include <zircon/syscalls.h>

#include <array>
#include <cstdint>
#include <cstring>
#include <limits>
#include <memory>
#include <string>
#include <string_view>
#include <type_traits>
#include <vector>

#include <fbl/macros.h>

#include "src/connectivity/bluetooth/lib/cpp-type/member_pointer_traits.h"
#include "src/connectivity/bluetooth/lib/cpp-type/to_std_array.h"

namespace bt {

class BufferView;
class MutableBufferView;
class MutableByteBuffer;

// Interface for buffer implementations with various allocation schemes.
class ByteBuffer {
 public:
  using const_iterator = const uint8_t*;
  using iterator = const_iterator;

  virtual ~ByteBuffer() = default;

  // Returns a pointer to the beginning of this buffer. The return value is
  // undefined if the buffer has size 0.
  virtual const uint8_t* data() const = 0;

  // Returns the number of bytes contained in this packet.
  virtual size_t size() const = 0;

  // Returns a BufferView that points to the region of this buffer starting at
  // |pos| of |size| bytes. If |size| is larger than the size of this BufferView
  // then the returned region will contain all bytes in this buffer starting at
  // |pos|.
  //
  // For example:
  //
  //  // Get a view of all of |my_buffer|.
  //  const BufferView view = my_buffer.view();
  //
  //  // Get a view of the first 5 bytes in |my_buffer| (assuming |my_buffer| is
  //  // large enough).
  //  view = my_buffer.view(0, 5);
  //
  //  // Get a view of |my_buffer| starting at the second byte.
  //  view = my_buffer.view(2);
  //
  //
  // WARNING:
  //
  // A BufferView is only valid as long as the buffer that it points to is
  // valid. Care should be taken to ensure that a BufferView does not outlive
  // its backing buffer.
  BufferView view(size_t pos = 0, size_t size = std::numeric_limits<std::size_t>::max()) const;

  // Copies all bytes of this buffer into |out_buffer|. |out_buffer| must be large enough to
  // accommodate the result of this operation.
  void Copy(MutableByteBuffer* out_buffer) const;

  // Copies |size| bytes of this buffer into |out_buffer| starting at offset |pos|. |out_buffer|
  // must be large enough to accommodate the result of this operation.
  void Copy(MutableByteBuffer* out_buffer, size_t pos, size_t size) const;

  // Iterator functions.
  iterator begin() const { return cbegin(); }
  iterator end() const { return cend(); }
  virtual const_iterator cbegin() const = 0;
  virtual const_iterator cend() const = 0;

  // Read-only random access operator.
  inline const uint8_t& operator[](size_t pos) const {
    ZX_ASSERT_MSG(pos < size(), "invalid offset (pos = %zu)", pos);
    return data()[pos];
  }

  // Converts the underlying buffer to the given type with bounds checking. The buffer is allowed
  // to be larger than T. The user is responsible for checking that the first sizeof(T) bytes
  // represent a valid instance of T.
  template <typename T>
  const T& As() const {
    // std::is_trivial_v would be a stronger guarantee that the buffer contains a valid T object,
    // but would disallow casting to types that have useful constructors, which might instead cause
    // uninitialized field(s) bugs for data encoding/decoding structs.
    static_assert(std::is_trivially_copyable_v<T>, "Can not reinterpret bytes");
    ZX_ASSERT(size() >= sizeof(T));
    return *reinterpret_cast<const T*>(data());
  }

  // Given a pointer to a member of a class, interpret the underlying buffer as a representation of
  // the class and return a copy of the member, with bounds checking for reading the representation.
  // Array elements (including multi-dimensional) will be returned as std::array. The buffer is
  // allowed to be larger than T. The user is responsible for checking that the first sizeof(T)
  // bytes represent a valid instance of T.
  //
  // Example:
  //   struct Foo { float bar[3]; int baz; char qux[]; };
  //   buffer.ReadMember<&Foo::bar>();  // OK, returns std::array<float, 3>
  //   buffer.ReadMember<&Foo::baz>();  // OK, returns int
  //   buffer.ReadMember<&Foo::qux>();  // Asserts, use ReadMember<&Foo::qux>(index) instead
  //
  // This functions similarly to C-style type punning at address
  //   |buffer.data() + offsetof(Foo, bar)|
  template <auto PointerToMember>
  auto ReadMember() const {
    using ClassT = typename bt_lib_cpp_type::MemberPointerTraits<PointerToMember>::ClassType;
    ZX_ASSERT_MSG(sizeof(ClassT) <= this->size(),
                  "insufficient buffer (class size: %zu, buffer size: %zu)", sizeof(ClassT),
                  this->size());
    using MemberT = typename bt_lib_cpp_type::MemberPointerTraits<PointerToMember>::MemberType;
    if constexpr (std::is_array_v<MemberT>) {
      static_assert(std::extent_v<MemberT> > 0,
                    "use indexed overload of ReadMember for flexible array members");
    }
    using ReturnType = std::remove_cv_t<bt_lib_cpp_type::ToStdArrayT<MemberT>>;

    // std::array is required to be an aggregate that's list-initialized per ISO/IEC 14882:2017(E)
    // § 26.3.7.1 [array.overview] ¶ 2, so its layout's initial run is identical to a raw array.
    static_assert(sizeof(MemberT) <= sizeof(ReturnType));
    static_assert(std::is_trivially_copyable_v<MemberT>, "unsafe to copy representation");
    static_assert(std::is_trivially_copyable_v<ReturnType>, "unsafe to copy representation");
    ReturnType out{};
    const size_t offset = bt_lib_cpp_type::MemberPointerTraits<PointerToMember>::offset();
    CopyRaw(/*dst_data=*/std::addressof(out), /*dst_capacity=*/sizeof(out), /*src_offset=*/offset,
            /*copy_size=*/sizeof(MemberT));
    return out;
  }

  // Given a pointer to an array (or smart array) member of a class, interpret the underlying buffer
  // as a representation of the class and return a copy of the member's |index - 1|-th element, with
  // bounds checking for the indexing and reading representation bytes. Multi-dimensional arrays
  // will return array elements as std::array. The buffer is allowed to be larger than T. The user
  // is responsible for checking that the first sizeof(T) bytes represent a valid instance of T.
  //
  // Example:
  //   struct Foo { float bar[3]; int baz; char qux[]; };
  //   buffer.ReadMember<&Foo::bar>(2);  // OK
  //   buffer.ReadMember<&Foo::qux>(3);  // OK, checked against buffer.size()
  //   buffer.ReadMember<&Foo::bar>(3);  // Asserts because out-of-bounds on Foo::bar
  //
  // This functions similarly to C-style type punning at address
  //   |buffer.data() + offsetof(Foo, bar) + index * sizeof(bar[0])|
  // but performs bounds checking and returns a valid type-punned object.
  template <auto PointerToMember>
  auto ReadMember(size_t index) const {
    // From the ReadMember<&Foo::bar>(2) example, ClassT = Foo
    using ClassT = typename bt_lib_cpp_type::MemberPointerTraits<PointerToMember>::ClassType;
    ZX_ASSERT_MSG(sizeof(ClassT) <= this->size(),
                  "insufficient buffer (class size: %zu, buffer size: %zu)", sizeof(ClassT),
                  this->size());

    // From the ReadMember<&Foo::bar>(2) example, MemberT = float[3]
    using MemberT = typename bt_lib_cpp_type::MemberPointerTraits<PointerToMember>::MemberType;
    static_assert(std::is_trivially_copyable_v<MemberT>, "unsafe to copy representation");

    // From the ReadMember<&Foo::bar>(2) example, MemberAsStdArrayT = std::array<float, 3>
    using MemberAsStdArrayT = bt_lib_cpp_type::ToStdArrayT<MemberT>;

    // Check array bounds
    constexpr size_t kArraySize = std::tuple_size_v<MemberAsStdArrayT>;
    const size_t base_offset = bt_lib_cpp_type::MemberPointerTraits<PointerToMember>::offset();
    if constexpr (kArraySize > 0) {
      // std::array is required to be an aggregate that's list-initialized per ISO/IEC 14882:2017(E)
      // § 26.3.7.1 [array.overview] ¶ 2, so we can rely on the initial run of its layout, but in
      // the technically possible but unlikely case that it contains additional bytes, we can't use
      // its size for array indexing calculations.
      static_assert(sizeof(MemberAsStdArrayT) == sizeof(MemberT));
      ZX_ASSERT_MSG(index < kArraySize, "index past array bounds (index: %zu, array size: %zu)",
                    index, kArraySize);
    } else {
      // Allow flexible array members (at the end of structs) that have zero length
      ZX_ASSERT_MSG(base_offset == sizeof(ClassT), "read from zero-length array");
    }

    // From the ReadMember<&Foo::bar>(2) example, ElementT = float
    using ElementT = std::remove_cv_t<typename MemberAsStdArrayT::value_type>;
    static_assert(std::is_trivially_copyable_v<ElementT>, "unsafe to copy representation");
    const size_t offset = base_offset + index * sizeof(ElementT);
    ElementT element{};
    CopyRaw(/*dst_data=*/std::addressof(element), /*dst_capacity=*/sizeof(ElementT),
            /*src_offset=*/offset, /*copy_size=*/sizeof(ElementT));
    return element;
  }

  bool operator==(const ByteBuffer& other) const {
    if (size() != other.size()) {
      return false;
    }
    return (memcmp(data(), other.data(), size()) == 0);
  }

  // Returns the contents of this buffer as a C++ string-like object without
  // copying its contents.
  std::string_view AsString() const;

  // Returns the contents of this buffer as a C++ string after copying its
  // contents.
  std::string ToString() const;

  // Returns a copy of the contents of this buffer in a std::vector.
  std::vector<uint8_t> ToVector() const;

 private:
  void CopyRaw(void* dst_data, size_t dst_capacity, size_t src_offset, size_t copy_size) const;
};

using ByteBufferPtr = std::unique_ptr<ByteBuffer>;

// Mutable extension to the ByteBuffer interface. This provides methods that
// allows direct mutable access to the underlying buffer.
class MutableByteBuffer : public ByteBuffer {
 public:
  ~MutableByteBuffer() override = default;

  // Returns a pointer to the beginning of this buffer. The return value is
  // undefined if the buffer has size 0.
  virtual uint8_t* mutable_data() = 0;

  // Random access operator that allows mutations.
  inline uint8_t& operator[](size_t pos) {
    ZX_ASSERT_MSG(pos < size(), "invalid offset (pos = %zu)", pos);
    return mutable_data()[pos];
  }

  // Converts the underlying buffer to a mutable reference to the given type, with bounds checking.
  // The buffer is allowed to be larger than T. The user is responsible for checking that the first
  // sizeof(T) bytes represents a valid instance of T.
  template <typename T>
  T& AsMutable() {
    static_assert(std::is_trivially_copyable_v<T>, "Can not reinterpret bytes");
    ZX_ASSERT(size() >= sizeof(T));
    return *reinterpret_cast<T*>(mutable_data());
  }

  // Writes the contents of |data| into this buffer starting at |pos|.
  inline void Write(const ByteBuffer& data, size_t pos = 0) {
    Write(data.data(), data.size(), pos);
  }

  // Writes |size| octets of data starting from |data| into this buffer starting
  // at |pos|. |data| must point to a valid piece of memory if |size| is
  // non-zero. If |size| is zero, then this operation is a NOP.
  void Write(const uint8_t* data, size_t size, size_t pos = 0);

  // Writes the byte interpretation of |data| at |pos|, overwriting the octets
  // from pos to pos + sizeof(T).
  // There must be enough space in the buffer to write T.
  // If T is an array of known bounds, the entire array will be written.
  template <typename T>
  void WriteObj(const T& data, size_t pos = 0) {
    // ByteBuffers are (mostly?) not TriviallyCopyable, but check this first for the error to be
    // useful.
    static_assert(!std::is_base_of_v<ByteBuffer, T>, "ByteBuffer passed to WriteObj; use Write");
    static_assert(!std::is_pointer_v<T>, "Pointer passed to WriteObj, deref or use Write");
    static_assert(std::is_trivially_copyable_v<T>, "Unsafe to peek byte representation");
    Write(reinterpret_cast<const uint8_t*>(&data), sizeof(T), pos);
  }

  // Behaves exactly like ByteBuffer::View but returns the result in a
  // MutableBufferView instead.
  //
  // WARNING:
  //
  // A BufferView is only valid as long as the buffer that it points to is
  // valid. Care should be taken to ensure that a BufferView does not outlive
  // its backing buffer.
  MutableBufferView mutable_view(size_t pos = 0,
                                 size_t size = std::numeric_limits<std::size_t>::max());

  // Sets the contents of the buffer to 0s.
  void SetToZeros() { Fill(0); }

  // Fills the contents of the buffer with random bytes.
  void FillWithRandomBytes();

  // Fills the contents of the buffer with the given value.
  virtual void Fill(uint8_t value) = 0;
};

using MutableByteBufferPtr = std::unique_ptr<MutableByteBuffer>;

// A ByteBuffer with static storage duration. Instances of this class are
// copyable. Due to the static buffer storage duration, move semantics work the
// same way as copy semantics, i.e. moving an instance will copy the buffer
// contents.
template <size_t BufferSize>
class StaticByteBuffer : public MutableByteBuffer {
 public:
  StaticByteBuffer() { static_assert(BufferSize, "|BufferSize| must be non-zero"); }
  ~StaticByteBuffer() override = default;

  // Variadic template constructor to initialize a StaticByteBuffer using a parameter pack e.g.:
  //
  //   StaticByteBuffer<3> foo{0x00, 0x01, 0x02};
  //   StaticByteBuffer<3> bar({0x00, 0x01, 0x02});
  //
  // The class's |BufferSize| template parameter, if explicitly provided, will be checked against
  // the number of initialization elements provided.
  template <typename... T>
  explicit StaticByteBuffer(T... bytes) : buffer_{{static_cast<uint8_t>(bytes)...}} {
    static_assert(BufferSize, "|BufferSize| must be non-zero");
    static_assert(BufferSize == sizeof...(T), "|BufferSize| must match initializer list count");
  }

  // ByteBuffer overrides
  const uint8_t* data() const override { return buffer_.data(); }
  size_t size() const override { return buffer_.size(); }
  const_iterator cbegin() const override { return buffer_.cbegin(); }
  const_iterator cend() const override { return buffer_.cend(); }

  // MutableByteBuffer overrides:
  uint8_t* mutable_data() override { return buffer_.data(); }
  void Fill(uint8_t value) override { buffer_.fill(value); }

 private:
  std::array<uint8_t, BufferSize> buffer_;
};

// Template deduction guide for the |BufferSize| class template parameter using the number of
// parameters passed into the templated parameter pack constructor. This allows |BufferSize| to be
// omitted when it should be deduced from the initializer:
//
//   StaticByteBuffer buffer(0x00, 0x01, 0x02);
//
template <typename... T>
StaticByteBuffer(T... bytes) -> StaticByteBuffer<sizeof...(T)>;

// Wrapper for the variadic template StaticByteBuffer constructor that deduces
// the value of the |BufferSize| template parameter from the given input. This
// way one can construct a StaticByteBuffer without hard-coding the size of the
// buffer like so:
//
//   auto buffer = CreateStaticByteBuffer(0x01, 0x02, 0x03);
//
template <typename... T>
StaticByteBuffer<sizeof...(T)> CreateStaticByteBuffer(T... bytes) {
  return StaticByteBuffer<sizeof...(T)>{bytes...};
}

// A ByteBuffer with dynamic storage duration. The underlying buffer is
// allocated using malloc. Instances of this class are move-only.
class DynamicByteBuffer : public MutableByteBuffer {
 public:
  // The default constructor creates an empty buffer with size 0.
  DynamicByteBuffer();
  ~DynamicByteBuffer() override = default;

  // Allocates a new buffer with |buffer_size| bytes.
  explicit DynamicByteBuffer(size_t buffer_size);

  // Copies the contents of |buffer|.
  explicit DynamicByteBuffer(const ByteBuffer& buffer);
  DynamicByteBuffer(const DynamicByteBuffer& buffer);

  // Takes ownership of |buffer| and avoids allocating a new buffer. Since this
  // constructor performs a simple assignment, the caller must make sure that
  // the buffer pointed to by |buffer| actually contains |buffer_size| bytes.
  DynamicByteBuffer(size_t buffer_size, std::unique_ptr<uint8_t[]> buffer);

  // Move constructor and assignment operator
  DynamicByteBuffer(DynamicByteBuffer&& other);
  DynamicByteBuffer& operator=(DynamicByteBuffer&& other);

  // Copy assignment is prohibited.
  DynamicByteBuffer& operator=(const DynamicByteBuffer&) = delete;

  // ByteBuffer overrides:
  const uint8_t* data() const override;
  size_t size() const override;
  const_iterator cbegin() const override;
  const_iterator cend() const override;

  // MutableByteBuffer overrides:
  uint8_t* mutable_data() override;
  void Fill(uint8_t value) override;

 private:
  // Pointer to the underlying buffer, which is owned and managed by us.
  size_t buffer_size_ = 0u;
  std::unique_ptr<uint8_t[]> buffer_;
};

// A ByteBuffer that does not own the memory that it points to but rather
// provides an immutable view over it.
//
// WARNING:
//
// A BufferView is only valid as long as the buffer that it points to is
// valid. Care should be taken to ensure that a BufferView does not outlive
// its backing buffer.
class BufferView final : public ByteBuffer {
 public:
  BufferView(const void* bytes, size_t size);
  ~BufferView() override = default;

  explicit BufferView(const ByteBuffer& buffer,
                      size_t size = std::numeric_limits<std::size_t>::max());
  explicit BufferView(std::string_view string);
  explicit BufferView(const std::vector<uint8_t>& vec);

  // The default constructor initializes this to an empty buffer.
  BufferView();

  // ByteBuffer overrides:
  const uint8_t* data() const override;
  size_t size() const override;
  const_iterator cbegin() const override;
  const_iterator cend() const override;

 private:
  size_t size_ = 0u;
  const uint8_t* bytes_ = nullptr;
};

// A ByteBuffer that does not own the memory that it points to but rather
// provides a mutable view over it.
//
// WARNING:
//
// A BufferView is only valid as long as the buffer that it points to is
// valid. Care should be taken to ensure that a BufferView does not outlive
// its backing buffer.
class MutableBufferView final : public MutableByteBuffer {
 public:
  explicit MutableBufferView(MutableByteBuffer* buffer);
  MutableBufferView(void* bytes, size_t size);
  ~MutableBufferView() override = default;

  // The default constructor initializes this to an empty buffer.
  MutableBufferView();

  // ByteBuffer overrides:
  const uint8_t* data() const override;
  size_t size() const override;
  const_iterator cbegin() const override;
  const_iterator cend() const override;

  // MutableByteBuffer overrides:
  uint8_t* mutable_data() override;
  void Fill(uint8_t value) override;

 private:
  size_t size_ = 0u;
  uint8_t* bytes_ = nullptr;
};

}  // namespace bt

#endif  // SRC_CONNECTIVITY_BLUETOOTH_CORE_BT_HOST_COMMON_BYTE_BUFFER_H_
