#ifndef ANDROID_PDX_UTILITY_H_
#define ANDROID_PDX_UTILITY_H_

#include <cstdint>
#include <iterator>

#include <pdx/rpc/sequence.h>

// Utilities for testing object serialization.

namespace android {
namespace pdx {

class ByteBuffer {
 public:
  using iterator = uint8_t*;
  using const_iterator = const uint8_t*;
  using size_type = size_t;

  ByteBuffer() = default;
  ByteBuffer(const ByteBuffer& other) {
    resize(other.size());
    if (other.size())
      memcpy(data_, other.data(), other.size());
  }

  ByteBuffer& operator=(const ByteBuffer& other) {
    resize(other.size());
    if (other.size())
      memcpy(data_, other.data(), other.size());
    return *this;
  }

  ByteBuffer& operator=(ByteBuffer&& other) {
    std::swap(data_, other.data_);
    std::swap(size_, other.size_);
    std::swap(capacity_, other.capacity_);
    other.clear();
    return *this;
  }

  inline const uint8_t* data() const { return data_; }
  inline uint8_t* data() { return data_; }
  inline size_t size() const { return size_; }
  inline size_t capacity() const { return capacity_; }

  iterator begin() { return data_; }
  const_iterator begin() const { return data_; }
  iterator end() { return data_ + size_; }
  const_iterator end() const { return data_ + size_; }

  inline bool operator==(const ByteBuffer& other) const {
    return size_ == other.size_ &&
           (size_ == 0 || memcmp(data_, other.data_, size_) == 0);
  }

  inline bool operator!=(const ByteBuffer& other) const {
    return !operator==(other);
  }

  inline void reserve(size_t size) {
    if (size <= capacity_)
      return;
    // Find next power of 2 (assuming the size is 32 bits for now).
    size--;
    size |= size >> 1;
    size |= size >> 2;
    size |= size >> 4;
    size |= size >> 8;
    size |= size >> 16;
    size++;
    void* new_data = data_ ? realloc(data_, size) : malloc(size);
    // TODO(avakulenko): Check for allocation failures.
    data_ = static_cast<uint8_t*>(new_data);
    capacity_ = size;
  }

  inline void resize(size_t size) {
    reserve(size);
    size_ = size;
  }

  inline uint8_t* grow_by(size_t size_delta) {
    size_t old_size = size_;
    resize(old_size + size_delta);
    return data_ + old_size;
  }

  inline void clear() { size_ = 0; }

 private:
  uint8_t* data_{nullptr};
  size_t size_{0};
  size_t capacity_{0};
};

// Utility functions to increment/decrement void pointers to data buffers.
template <typename OFFSET_T>
inline const void* AdvancePointer(const void* ptr, OFFSET_T offset) {
  return static_cast<const uint8_t*>(ptr) + offset;
}

template <typename OFFSET_T>
inline void* AdvancePointer(void* ptr, OFFSET_T offset) {
  return static_cast<uint8_t*>(ptr) + offset;
}

inline ptrdiff_t PointerDistance(const void* end, const void* begin) {
  return static_cast<const uint8_t*>(end) - static_cast<const uint8_t*>(begin);
}

// Utility to build sequences of types.
template <typename, typename>
struct AppendTypeSequence;

template <typename T, typename... S, template <typename...> class TT>
struct AppendTypeSequence<T, TT<S...>> {
  using type = TT<S..., T>;
};

// Utility to generate repeated types.
template <typename T, std::size_t N, template <typename...> class TT>
struct RepeatedType {
  using type = typename AppendTypeSequence<
      T, typename RepeatedType<T, N - 1, TT>::type>::type;
};

template <typename T, template <typename...> class TT>
struct RepeatedType<T, 0, TT> {
  using type = TT<>;
};

template <typename V, typename S>
inline V ReturnValueHelper(V value, S /*ignore*/) {
  return value;
}

template <typename R, typename V, size_t... S>
inline R GetNTupleHelper(V value, rpc::IndexSequence<S...>) {
  return std::make_tuple(ReturnValueHelper(value, S)...);
}

// Returns an N-tuple of type std::tuple<T,...T> containing |value| in each
// element.
template <size_t N, typename T,
          typename R = typename RepeatedType<T, N, std::tuple>::type>
inline R GetNTuple(T value) {
  return GetNTupleHelper<R>(value, rpc::MakeIndexSequence<N>{});
}

class NoOpOutputResourceMapper : public OutputResourceMapper {
 public:
  Status<FileReference> PushFileHandle(const LocalHandle& handle) override {
    return handle.Get();
  }

  Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override {
    return handle.Get();
  }

  Status<FileReference> PushFileHandle(const RemoteHandle& handle) override {
    return handle.Get();
  }

  Status<ChannelReference> PushChannelHandle(
      const LocalChannelHandle& handle) override {
    return handle.value();
  }

  Status<ChannelReference> PushChannelHandle(
      const BorrowedChannelHandle& handle) override {
    return handle.value();
  }

  Status<ChannelReference> PushChannelHandle(
      const RemoteChannelHandle& handle) override {
    return handle.value();
  }
};

class NoOpInputResourceMapper : public InputResourceMapper {
 public:
  bool GetFileHandle(FileReference ref, LocalHandle* handle) override {
    *handle = LocalHandle{ref};
    return true;
  }

  bool GetChannelHandle(ChannelReference ref,
                        LocalChannelHandle* handle) override {
    *handle = LocalChannelHandle{nullptr, ref};
    return true;
  }
};

class NoOpResourceMapper : public NoOpOutputResourceMapper,
                           public NoOpInputResourceMapper {};

// Simple implementation of the payload interface, required by
// Serialize/Deserialize. This is intended for test cases, where compatibility
// with std::vector is helpful.
class Payload : public MessageWriter,
                public MessageReader,
                public OutputResourceMapper {
 public:
  using BaseType = ByteBuffer;
  using iterator = typename BaseType::iterator;
  using const_iterator = typename BaseType::const_iterator;
  using size_type = typename BaseType::size_type;

  Payload() = default;
  explicit Payload(size_type count, uint8_t value = 0) { Append(count, value); }
  Payload(const Payload& other) : buffer_(other.buffer_) {}
  Payload(const std::initializer_list<uint8_t>& initializer) {
    buffer_.resize(initializer.size());
    std::copy(initializer.begin(), initializer.end(), buffer_.begin());
  }

  Payload& operator=(const Payload& other) {
    buffer_ = other.buffer_;
    read_pos_ = 0;
    return *this;
  }
  Payload& operator=(const std::initializer_list<uint8_t>& initializer) {
    buffer_.resize(initializer.size());
    std::copy(initializer.begin(), initializer.end(), buffer_.begin());
    read_pos_ = 0;
    return *this;
  }

  // Compares Payload with Payload.
  bool operator==(const Payload& other) const {
    return buffer_ == other.buffer_;
  }
  bool operator!=(const Payload& other) const {
    return buffer_ != other.buffer_;
  }

  // Compares Payload with std::vector.
  template <typename Type, typename AllocatorType>
  typename std::enable_if<sizeof(Type) == sizeof(uint8_t), bool>::type
  operator==(const std::vector<Type, AllocatorType>& other) const {
    return buffer_.size() == other.size() &&
           memcmp(buffer_.data(), other.data(), other.size()) == 0;
  }
  template <typename Type, typename AllocatorType>
  typename std::enable_if<sizeof(Type) == sizeof(uint8_t), bool>::type
  operator!=(const std::vector<Type, AllocatorType>& other) const {
    return !operator!=(other);
  }

  iterator begin() { return buffer_.begin(); }
  const_iterator begin() const { return buffer_.begin(); }
  iterator end() { return buffer_.end(); }
  const_iterator end() const { return buffer_.end(); }

  void Append(size_type count, uint8_t value) {
    auto* data = buffer_.grow_by(count);
    std::fill(data, data + count, value);
  }

  void Clear() {
    buffer_.clear();
    file_handles_.clear();
    read_pos_ = 0;
  }

  void Rewind() { read_pos_ = 0; }

  uint8_t* Data() { return buffer_.data(); }
  const uint8_t* Data() const { return buffer_.data(); }
  size_type Size() const { return buffer_.size(); }

  // MessageWriter
  void* GetNextWriteBufferSection(size_t size) override {
    return buffer_.grow_by(size);
  }

  OutputResourceMapper* GetOutputResourceMapper() override { return this; }

  // OutputResourceMapper
  Status<FileReference> PushFileHandle(const LocalHandle& handle) override {
    if (handle) {
      const int ref = file_handles_.size();
      file_handles_.push_back(handle.Get());
      return ref;
    } else {
      return handle.Get();
    }
  }

  Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override {
    if (handle) {
      const int ref = file_handles_.size();
      file_handles_.push_back(handle.Get());
      return ref;
    } else {
      return handle.Get();
    }
  }

  Status<FileReference> PushFileHandle(const RemoteHandle& handle) override {
    return handle.Get();
  }

  Status<ChannelReference> PushChannelHandle(
      const LocalChannelHandle& handle) override {
    if (handle) {
      const int ref = file_handles_.size();
      file_handles_.push_back(handle.value());
      return ref;
    } else {
      return handle.value();
    }
  }

  Status<ChannelReference> PushChannelHandle(
      const BorrowedChannelHandle& handle) override {
    if (handle) {
      const int ref = file_handles_.size();
      file_handles_.push_back(handle.value());
      return ref;
    } else {
      return handle.value();
    }
  }

  Status<ChannelReference> PushChannelHandle(
      const RemoteChannelHandle& handle) override {
    return handle.value();
  }

  // MessageReader
  BufferSection GetNextReadBufferSection() override {
    return {buffer_.data() + read_pos_, &*buffer_.end()};
  }

  void ConsumeReadBufferSectionData(const void* new_start) override {
    read_pos_ = PointerDistance(new_start, buffer_.data());
  }

  InputResourceMapper* GetInputResourceMapper() override {
    return &input_resource_mapper_;
  }

  const int* FdArray() const { return file_handles_.data(); }
  std::size_t FdCount() const { return file_handles_.size(); }

 private:
  NoOpInputResourceMapper input_resource_mapper_;
  ByteBuffer buffer_;
  std::vector<int> file_handles_;
  size_t read_pos_{0};
};

}  // namespace pdx
}  // namespace android

// Helper macros for branch prediction hinting.
#ifdef __GNUC__
#define PDX_LIKELY(x) __builtin_expect(!!(x), true)
#define PDX_UNLIKELY(x) __builtin_expect(!!(x), false)
#else
#define PDX_LIKELY(x) (x)
#define PDX_UNLIKELY(x) (x)
#endif

#endif  // ANDROID_PDX_UTILITY_H_
