// 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 <cstddef>
#include <initializer_list>
#include <iterator>
#include <limits>
#include <new>
#include <type_traits>
#include <utility>

namespace pw {
namespace vector_impl {

template <typename I>
using IsIterator = std::negation<
    std::is_same<typename std::iterator_traits<I>::value_type, void>>;

// Used as kMaxSize in the generic-size Vector<T> interface.
inline constexpr size_t kGeneric = size_t(-1);

}  // namespace vector_impl

// The Vector class is similar to std::vector, except it is backed by a
// fixed-size buffer. Vectors must be declared with an explicit maximum size
// (e.g. Vector<int, 10>) but vectors can be used and referred to without the
// max size template parameter (e.g. Vector<int>).
//
// To allow referring to a pw::Vector without an explicit maximum size, all
// Vector classes inherit from Vector<T, vector_impl::kGeneric>, which stores
// the maximum size in a variable. This allows Vectors to be used without having
// to know their maximum size at compile time. It also keeps code size small
// since function implementations are shared for all maximum sizes.
template <typename T, size_t kMaxSize = vector_impl::kGeneric>
class Vector : public Vector<T, vector_impl::kGeneric> {
 public:
  using typename Vector<T, vector_impl::kGeneric>::value_type;
  using typename Vector<T, vector_impl::kGeneric>::size_type;
  using typename Vector<T, vector_impl::kGeneric>::difference_type;
  using typename Vector<T, vector_impl::kGeneric>::reference;
  using typename Vector<T, vector_impl::kGeneric>::const_reference;
  using typename Vector<T, vector_impl::kGeneric>::pointer;
  using typename Vector<T, vector_impl::kGeneric>::const_pointer;
  using typename Vector<T, vector_impl::kGeneric>::iterator;
  using typename Vector<T, vector_impl::kGeneric>::const_iterator;
  using typename Vector<T, vector_impl::kGeneric>::reverse_iterator;
  using typename Vector<T, vector_impl::kGeneric>::const_reverse_iterator;

  // Construct
  Vector() noexcept : Vector<T, vector_impl::kGeneric>(kMaxSize) {}

  Vector(size_type count, const T& value)
      : Vector<T, vector_impl::kGeneric>(kMaxSize, count, value) {}

  explicit Vector(size_type count)
      : Vector<T, vector_impl::kGeneric>(kMaxSize, count, T()) {}

  template <
      typename Iterator,
      typename...,
      typename = std::enable_if_t<vector_impl::IsIterator<Iterator>::value>>
  Vector(Iterator first, Iterator last)
      : Vector<T, vector_impl::kGeneric>(kMaxSize, first, last) {}

  template <size_t kOtherMaxSize>
  Vector(const Vector<T, kOtherMaxSize>& other)
      : Vector<T, vector_impl::kGeneric>(kMaxSize, other) {}

  template <size_t kOtherMaxSize>
  Vector(Vector<T, kOtherMaxSize>&& other) noexcept
      : Vector<T, vector_impl::kGeneric>(kMaxSize, std::move(other)) {}

  Vector(std::initializer_list<T> list)
      : Vector<T, vector_impl::kGeneric>(kMaxSize, list) {}

  Vector& operator=(const Vector& other) {
    Vector<T>::assign(other.begin(), other.end());
    return *this;
  }

  template <size_t kOtherMaxSize>
  Vector& operator=(const Vector<T, kOtherMaxSize>& other) noexcept {
    Vector<T>::assign(other.begin(), other.end());
    return *this;
  }

  Vector& operator=(Vector&& other) noexcept {
    Vector<T>::operator=(std::move(other));
    return *this;
  }

  template <size_t kOtherMaxSize>
  Vector& operator=(Vector<T, kOtherMaxSize>&& other) noexcept {
    Vector<T>::operator=(std::move(other));
    return *this;
  }

  Vector& operator=(std::initializer_list<T> list) {
    this->assign(list.begin(), list.end());
    return *this;
  }

  // All other vector methods are implemented on the Vector<T> base class.

 private:
  friend class Vector<T, vector_impl::kGeneric>;

  static_assert(kMaxSize <= std::numeric_limits<size_type>::max());

  // Provides access to the underlying array as an array of T.
  pointer array() { return std::launder(reinterpret_cast<T*>(&array_)); }
  const_pointer array() const {
    return std::launder(reinterpret_cast<const T*>(&array_));
  }

  // Vector entries are stored as uninitialized memory blocks aligned correctly
  // for the type. Elements are initialized on demand with placement new.
  std::aligned_storage_t<sizeof(T), alignof(T)> array_[kMaxSize];
};

// Defines the generic-sized Vector<T> specialization, which serves as the base
// class for Vector<T> of any maximum size. Except for constructors, all Vector
// methods are implemented on this class.
template <typename T>
class Vector<T, vector_impl::kGeneric> {
 public:
  using value_type = T;

  // Use unsigned short instead of size_t. Since Vectors are statically
  // allocated, 65535 entries is a reasonable upper limit. This reduces Vector's
  // overhead by packing the size and capacity into 32 bits.
  using size_type = unsigned short;

  using difference_type = ptrdiff_t;
  using reference = value_type&;
  using const_reference = const value_type&;
  using pointer = T*;
  using const_pointer = const T*;
  using iterator = T*;
  using const_iterator = const T*;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

  // A vector without an explicit maximum size (Vector<T>) cannot be constructed
  // directly. Instead, construct a Vector<T, max_size>. Vectors of any max size
  // can be used through a Vector<T> pointer or reference.

  ~Vector() { clear(); }

  // Assign

  Vector& operator=(const Vector& other) {
    assign(other.begin(), other.end());
    return *this;
  }

  Vector& operator=(Vector&& other) noexcept {
    clear();
    MoveFrom(other);
    return *this;
  }

  Vector& operator=(std::initializer_list<T> list) {
    assign(list);
    return *this;
  }

  void assign(size_type count, const T& value) {
    clear();
    Append(count, value);
  }

  template <
      typename Iterator,
      typename...,
      typename = std::enable_if_t<vector_impl::IsIterator<Iterator>::value>>
  void assign(Iterator first, Iterator last) {
    clear();
    CopyFrom(first, last);
  }

  void assign(std::initializer_list<T> list) {
    assign(list.begin(), list.end());
  }

  // Access

  // TODO(hepler): Add an assert for bounds checking in at.
  reference at(size_type index) { return data()[index]; }
  const_reference at(size_type index) const { return data()[index]; }

  reference operator[](size_type index) { return data()[index]; }
  const_reference operator[](size_type index) const { return data()[index]; }

  reference front() { return data()[0]; }
  const_reference front() const { return data()[0]; }

  reference back() { return data()[size() - 1]; }
  const_reference back() const { return data()[size() - 1]; }

  // The underlying data is not part of the generic-length vector class. It is
  // provided in the derived class from which this instance was constructed. To
  // access the data, down-cast this to a Vector with a known max size, and
  // return a pointer to the start of the array, which is the same for all
  // vectors with explicit max size.
  T* data() noexcept { return static_cast<Vector<T, 1>*>(this)->array(); }
  const T* data() const noexcept {
    return static_cast<const Vector<T, 1>*>(this)->array();
  }

  // Iterate

  iterator begin() noexcept { return &data()[0]; }
  const_iterator begin() const noexcept { return &data()[0]; }
  const_iterator cbegin() const noexcept { return &data()[0]; }

  iterator end() noexcept { return &data()[size()]; }
  const_iterator end() const noexcept { return &data()[size()]; }
  const_iterator cend() const noexcept { return &data()[size()]; }

  reverse_iterator rbegin() noexcept { return reverse_iterator(end()); }
  const_reverse_iterator rbegin() const { return reverse_iterator(end()); }
  const_reverse_iterator crbegin() const noexcept {
    return reverse_iterator(cend());
  }

  reverse_iterator rend() noexcept { return reverse_iterator(begin()); }
  const_reverse_iterator rend() const { return reverse_iterator(begin()); }
  const_reverse_iterator crend() const noexcept {
    return reverse_iterator(cbegin());
  }

  // Size

  [[nodiscard]] bool empty() const noexcept { return size() == 0u; }

  // True if there is no free space in the vector. Operations that add elements
  // (push_back, insert, etc.) will fail if full() is true.
  [[nodiscard]] bool full() const noexcept { return size() == max_size(); }

  // Returns the number of elements in the Vector. Uses size_t instead of
  // size_type for consistency with other containers.
  size_t size() const noexcept { return size_; }

  // Returns the maximum number of elements in this Vector.
  size_t max_size() const noexcept { return max_size_; }

  size_t capacity() const noexcept { return max_size(); }

  // Modify

  void clear() noexcept;

  // TODO(hepler): insert, emplace, and erase are not yet implemented.
  //    Currently, items can only be added to or removed from the end.
  iterator insert(const_iterator index, const T& value);

  iterator insert(const_iterator index, T&& value);

  iterator insert(const_iterator index, size_type count, const T& value);

  template <typename Iterator>
  iterator insert(const_iterator index, Iterator first, Iterator last);

  iterator insert(const_iterator index, std::initializer_list<T> list);

  template <typename... Args>
  iterator emplace(const_iterator index, Args&&... args);

  iterator erase(const_iterator index);

  iterator erase(const_iterator first, const_iterator last);

  void push_back(const T& value) { emplace_back(value); }

  void push_back(T&& value) { emplace_back(std::move(value)); }

  template <typename... Args>
  void emplace_back(Args&&... args);

  void pop_back();

  void resize(size_type new_size) { resize(new_size, T()); }

  void resize(size_type new_size, const T& value);

 protected:
  // Vectors without an explicit size cannot be constructed directly. Instead,
  // the maximum size must be provided.
  explicit Vector(size_type max_size) noexcept : max_size_(max_size) {}

  Vector(size_type max_size, size_type count, const T& value)
      : Vector(max_size) {
    Append(count, value);
  }

  Vector(size_type max_size, size_type count) : Vector(max_size, count, T()) {}

  template <
      typename Iterator,
      typename...,
      typename = std::enable_if_t<vector_impl::IsIterator<Iterator>::value>>
  Vector(size_type max_size, Iterator first, Iterator last) : Vector(max_size) {
    CopyFrom(first, last);
  }

  Vector(size_type max_size, const Vector& other) : Vector(max_size) {
    CopyFrom(other.begin(), other.end());
  }

  Vector(size_type max_size, Vector&& other) noexcept : Vector(max_size) {
    MoveFrom(other);
  }

  Vector(size_type max_size, std::initializer_list<T> list) : Vector(max_size) {
    CopyFrom(list.begin(), list.end());
  }

 private:
  template <typename Iterator>
  void CopyFrom(Iterator first, Iterator last);

  void MoveFrom(Vector& other) noexcept;

  void Append(size_type count, const T& value);

  const size_type max_size_;
  size_type size_ = 0;
};

// Compare

template <typename T, size_t kLhsSize, size_t kRhsSize>
bool operator==(const Vector<T, kLhsSize>& lhs,
                const Vector<T, kRhsSize>& rhs) {
  return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}

template <typename T, size_t kLhsSize, size_t kRhsSize>
bool operator!=(const Vector<T, kLhsSize>& lhs,
                const Vector<T, kRhsSize>& rhs) {
  return !(lhs == rhs);
}

template <typename T, size_t kLhsSize, size_t kRhsSize>
bool operator<(const Vector<T, kLhsSize>& lhs, const Vector<T, kRhsSize>& rhs) {
  return std::lexicographical_compare(
      lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}

template <typename T, size_t kLhsSize, size_t kRhsSize>
bool operator<=(const Vector<T, kLhsSize>& lhs,
                const Vector<T, kRhsSize>& rhs) {
  return !(rhs < lhs);
}

template <typename T, size_t kLhsSize, size_t kRhsSize>
bool operator>(const Vector<T, kLhsSize>& lhs, const Vector<T, kRhsSize>& rhs) {
  return rhs < lhs;
}

template <typename T, size_t kLhsSize, size_t kRhsSize>
bool operator>=(const Vector<T, kLhsSize>& lhs,
                const Vector<T, kRhsSize>& rhs) {
  return !(lhs < rhs);
}

// Function implementations

template <typename T>
void Vector<T, vector_impl::kGeneric>::clear() noexcept {
  for (auto& item : *this) {
    item.~T();
  }
  size_ = 0;
}

template <typename T>
template <typename... Args>
void Vector<T, vector_impl::kGeneric>::emplace_back(Args&&... args) {
  if (!full()) {
    new (&data()[size_]) T(std::forward<Args>(args)...);
    size_ += 1;
  }
}

template <typename T>
void Vector<T, vector_impl::kGeneric>::pop_back() {
  if (!empty()) {
    back().~T();
    size_ -= 1;
  }
}

template <typename T>
void Vector<T, vector_impl::kGeneric>::resize(size_type new_size,
                                              const T& value) {
  if (size() < new_size) {
    Append(std::min(max_size(), size_t(new_size)) - size(), value);
  } else {
    while (size() > new_size) {
      pop_back();
    }
  }
}

template <typename T>
template <typename Iterator>
void Vector<T, vector_impl::kGeneric>::CopyFrom(Iterator first, Iterator last) {
  while (first != last) {
    push_back(*first++);
  }
}

template <typename T>
void Vector<T, vector_impl::kGeneric>::MoveFrom(Vector& other) noexcept {
  for (auto&& item : other) {
    emplace_back(std::move(item));
  }
  other.clear();
}

template <typename T>
void Vector<T, vector_impl::kGeneric>::Append(size_type count, const T& value) {
  for (size_t i = 0; i < count; ++i) {
    push_back(value);
  }
}

}  // namespace pw
