// 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 LIB_FIDL_LLCPP_VECTOR_VIEW_H_
#define LIB_FIDL_LLCPP_VECTOR_VIEW_H_

#include <lib/fidl/walker.h>
#include <zircon/fidl.h>

#include <iterator>
#include <type_traits>

#include "tracking_ptr.h"

namespace {
class LayoutChecker;
}  // namespace

namespace fidl {

// VectorView is the representation of a FIDL vector in LLCPP.
//
// VectorViews provide limited functionality to access and set fields of the
// vector and other objects like fidl::Array or std::vector must be used to
// construct it.
//
// VectorView's layout and data format must match fidl_vector_t as it will be
// reinterpret_casted into fidl_vector_t during linearization.
//
// Example:
// uint32_t arr[5] = { 1, 2, 3 };
// SomeLLCPPObject obj;
// obj.set_vec_field(VectorView(vv));
template <typename T>
class VectorView {
  template <typename>
  friend class VectorView;

  using marked_count = uint64_t;

  // The MSB of count_ stores whether or not data_ is owned by VectorView.
  static constexpr marked_count kOwnershipMask = internal::kVectorOwnershipMask;
  // The maximum count to avoid colliding with the ownership bit.
  static constexpr uint64_t kMaxCount = uint64_t(kOwnershipMask) - 1ULL;

 public:
  VectorView() {}

  VectorView(tracking_ptr<T[]>&& data, uint64_t count) {
    set_data_internal(std::move(data));
    set_count(count);
  }

  // Ideally these constructors wouldn't be needed, but automatic deduction into the tracking_ptr
  // doesn't currently work. A deduction guide can fix this, but it is C++17-only.
  VectorView(unowned_ptr_t<T> data, uint64_t count) : VectorView(tracking_ptr<T[]>(data), count) {}
  template <typename U = T, typename = std::enable_if_t<std::is_const<U>::value>>
  VectorView(unowned_ptr_t<std::remove_const_t<U>> data, uint64_t count)
      : VectorView(tracking_ptr<T[]>(data), count) {}
  VectorView(std::unique_ptr<T[]>&& data, uint64_t count)
      : VectorView(tracking_ptr<T[]>(std::move(data)), count) {}
  VectorView(std::nullptr_t data, uint64_t count) : VectorView(tracking_ptr<T[]>(data), count) {}
  // This constructor triggers a static assertion in tracking_ptr.
  template <typename U, typename = std::enable_if_t<!std::is_array<U>::value>>
  VectorView(U* data, uint64_t count) : VectorView(tracking_ptr<U[]>(data), count) {}

  template <typename U>
  VectorView(VectorView<U>&& other) {
    static_assert(
        std::is_same<T, U>::value || std::is_same<T, std::add_const_t<U>>::value,
        "VectorView<T> can only be move-constructed from VectorView<T> or VectorView<const T>");
    count_ = other.count_;
    data_ = other.data_;
    other.release();
  }

  ~VectorView() {
    if (is_owned()) {
      delete[] data_;
    }
  }

  template <typename U>
  VectorView& operator=(VectorView<U>&& other) {
    static_assert(std::is_same<T, U>::value || std::is_same<T, std::add_const_t<U>>::value,
                  "VectorView<T> can only be assigned from VectorView<T> or VectorView<const T>");
    if (data_ != nullptr && is_owned()) {
      delete[] data_;
    }
    count_ = other.count_;
    data_ = other.data_;
    other.release();
    return *this;
  }

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

  uint64_t count() const { return count_ & ~kOwnershipMask; }
  void set_count(uint64_t count) {
    if (count > kMaxCount) {
      abort();
    }
    count_ = count | (count_ & kOwnershipMask);
  }

  const T* data() const { return data_; }
  void set_data(tracking_ptr<T[]> data) { set_data_internal(std::move(data)); }

  T* mutable_data() const { return data_; }

  bool empty() const { return count() == 0; }

  const T& at(size_t offset) const { return data()[offset]; }
  T& at(size_t offset) { return mutable_data()[offset]; }

  const T& operator[](size_t offset) const { return at(offset); }
  T& operator[](size_t offset) { return at(offset); }

  T* begin() { return mutable_data(); }
  const T* begin() const { return data(); }
  const T* cbegin() const { return data(); }

  T* end() { return mutable_data() + count(); }
  const T* end() const { return data() + count(); }
  const T* cend() const { return data() + count(); }

  fidl_vector_t* impl() { return this; }

 private:
  void set_data_internal(tracking_ptr<T[]>&& data) {
    if (data_ != nullptr && is_owned()) {
      delete[] data_;
    }
    if (data.is_owned()) {
      count_ |= kOwnershipMask;
    } else {
      count_ &= ~kOwnershipMask;
    }
    data_ = data.get();
    data.release();
  }

  bool is_owned() const noexcept { return count_ & kOwnershipMask; }

  void release() {
    if (is_owned()) {
      // Match unique_ptr std::move behavior in owned and unowned case
      // (unowned case doesn't reset source).
      count_ = 0;
      data_ = nullptr;
    }
  }

  friend ::LayoutChecker;

  // The lower 63 bits of count_ are reserved to store the number of elements.
  // The MSB stores ownership of the data_ pointer.
  marked_count count_ = 0;
  T* data_ = nullptr;
};

}  // namespace fidl

namespace {
class LayoutChecker {
  static_assert(sizeof(fidl::VectorView<uint8_t>) == sizeof(fidl_vector_t),
                "VectorView size should match fidl_vector_t");
  static_assert(offsetof(fidl::VectorView<uint8_t>, count_) == offsetof(fidl_vector_t, count),
                "VectorView count offset should match fidl_vector_t");
  static_assert(sizeof(fidl::VectorView<uint8_t>::count_) == sizeof(fidl_vector_t::count),
                "VectorView count size should match fidl_vector_t");
  static_assert(offsetof(fidl::VectorView<uint8_t>, data_) == offsetof(fidl_vector_t, data),
                "VectorView data offset should match fidl_vector_t");
  static_assert(sizeof(fidl::VectorView<uint8_t>::data_) == sizeof(fidl_vector_t::data),
                "VectorView data size should match fidl_vector_t");
};

}  // namespace

#endif  // LIB_FIDL_LLCPP_VECTOR_VIEW_H_
