// Copyright 2019 Google LLC
//
// 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.

// View classes for arrays and bit arrays.
#ifndef EMBOSS_RUNTIME_CPP_EMBOSS_ARRAY_VIEW_H_
#define EMBOSS_RUNTIME_CPP_EMBOSS_ARRAY_VIEW_H_

#include <cstddef>
#include <iterator>
#include <tuple>
#include <type_traits>

#include "runtime/cpp/emboss_arithmetic.h"
#include "runtime/cpp/emboss_array_view.h"
#include "runtime/cpp/emboss_text_util.h"

namespace emboss {

// Forward declarations for use by WriteShorthandArrayCommentToTextStream.
namespace prelude {
template <class Parameters, class BitViewType>
class UIntView;
template <class Parameters, class BitViewType>
class IntView;
}  // namespace prelude

namespace support {

// Advance direction for ElementViewIterator.
enum class ElementViewIteratorDirection { kForward, kReverse };

// Iterator adapter for elements in a GenericArrayView.
template <class GenericArrayView, ElementViewIteratorDirection kDirection>
class ElementViewIterator {
 public:
  using iterator_category = ::std::random_access_iterator_tag;
  using value_type = typename GenericArrayView::ViewType;
  using difference_type = ::std::ptrdiff_t;
  using pointer = typename ::std::add_pointer<value_type>::type;
  using reference = typename ::std::add_lvalue_reference<value_type>::type;

  explicit ElementViewIterator(const GenericArrayView *array_view,
                               ::std::ptrdiff_t index)
      : array_view_(array_view), view_((*array_view)[index]), index_(index) {}

  ElementViewIterator() = default;

  reference operator*() { return view_; }

  pointer operator->() { return &view_; }

  ElementViewIterator &operator+=(difference_type d) {
    index_ += (kDirection == ElementViewIteratorDirection::kForward ? d : -d);
    view_ = (*array_view_)[index_];
    return *this;
  }

  ElementViewIterator &operator-=(difference_type d) { return *this += (-d); }

  ElementViewIterator &operator++() {
    *this += 1;
    return *this;
  }

  ElementViewIterator &operator--() {
    *this -= 1;
    return *this;
  }

  ElementViewIterator operator++(int) {
    auto copy = *this;
    ++(*this);
    return copy;
  }

  ElementViewIterator operator--(int) {
    auto copy = *this;
    --(*this);
    return copy;
  }

  ElementViewIterator operator+(difference_type d) const {
    auto copy = *this;
    copy += d;
    return copy;
  }

  ElementViewIterator operator-(difference_type d) const {
    return *this + (-d);
  }

  difference_type operator-(const ElementViewIterator &other) const {
    return kDirection == ElementViewIteratorDirection::kForward
               ? index_ - other.index_
               : other.index_ - index_;
  }

  bool operator==(const ElementViewIterator &other) const {
    return array_view_ == other.array_view_ && index_ == other.index_;
  }

  bool operator!=(const ElementViewIterator &other) const {
    return !(*this == other);
  }

  bool operator<(const ElementViewIterator &other) const {
    return kDirection == ElementViewIteratorDirection::kForward
               ? index_ < other.index_
               : other.index_ < index_;
  }

  bool operator<=(const ElementViewIterator &other) const {
    return kDirection == ElementViewIteratorDirection::kForward
               ? index_ <= other.index_
               : other.index_ <= index_;
  }

  bool operator>(const ElementViewIterator &other) const {
    return !(*this <= other);
  }

  bool operator>=(const ElementViewIterator &other) const {
    return !(*this < other);
  }

 private:
  const GenericArrayView *array_view_;
  typename GenericArrayView::ViewType view_;
  ::std::ptrdiff_t index_;
};

// View for an array in a structure.
//
// ElementView should be the view class for a single array element (e.g.,
// UIntView<...> or ArrayView<...>).
//
// BufferType is the storage type that will be passed into the array.
//
// kElementSize is the fixed size of a single element, in addressable units.
//
// kAddressableUnitSize is the size of a single addressable unit.  It should be
// either 1 (one bit) or 8 (one byte).
//
// ElementViewParameterTypes is a list of the types of parameters which must be
// passed down to each element of the array.  ElementViewParameterTypes can be
// empty.
template <class ElementView, class BufferType, ::std::size_t kElementSize,
          ::std::size_t kAddressableUnitSize,
          typename... ElementViewParameterTypes>
class GenericArrayView final {
 public:
  using ViewType = ElementView;
  using ForwardIterator =
      ElementViewIterator<GenericArrayView,
                          ElementViewIteratorDirection::kForward>;
  using ReverseIterator =
      ElementViewIterator<GenericArrayView,
                          ElementViewIteratorDirection::kReverse>;

  GenericArrayView() : buffer_() {}
  explicit GenericArrayView(const ElementViewParameterTypes &... parameters,
                            BufferType buffer)
      : parameters_{parameters...}, buffer_{buffer} {}

  ElementView operator[](::std::size_t index) const {
    return IndexOperatorHelper<sizeof...(ElementViewParameterTypes) ==
                               0>::ConstructElement(parameters_, buffer_,
                                                    index);
  }

  ForwardIterator begin() const { return ForwardIterator(this, 0); }
  ForwardIterator end() const { return ForwardIterator(this, ElementCount()); }
  ReverseIterator rbegin() const {
    return ReverseIterator(this, ElementCount() - 1);
  }
  ReverseIterator rend() const { return ReverseIterator(this, -1); }

  // In order to selectively enable SizeInBytes and SizeInBits, it is
  // necessary to make them into templates.  Further, it is necessary for
  // ::std::enable_if to have a dependency on the template parameter, otherwise
  // SFINAE won't kick in.  Thus, these are templated on an int, and that int
  // is (spuriously) used as the left argument to `,` in the enable_if
  // condition.  The explicit cast to void is needed to silence GCC's
  // -Wunused-value.
  template <int N = 0>
  typename ::std::enable_if<((void)N, kAddressableUnitSize == 8),
                            ::std::size_t>::type
  SizeInBytes() const {
    return buffer_.SizeInBytes();
  }
  template <int N = 0>
  typename ::std::enable_if<((void)N, kAddressableUnitSize == 1),
                            ::std::size_t>::type
  SizeInBits() const {
    return buffer_.SizeInBits();
  }

  ::std::size_t ElementCount() const { return SizeOfBuffer() / kElementSize; }
  bool Ok() const {
    if (!buffer_.Ok()) return false;
    if (SizeOfBuffer() % kElementSize != 0) return false;
    for (::std::size_t i = 0; i < ElementCount(); ++i) {
      if (!(*this)[i].Ok()) return false;
    }
    return true;
  }
  template <class OtherElementView, class OtherBufferType>
  bool Equals(
      const GenericArrayView<OtherElementView, OtherBufferType, kElementSize,
                             kAddressableUnitSize> &other) const {
    if (ElementCount() != other.ElementCount()) return false;
    for (::std::size_t i = 0; i < ElementCount(); ++i) {
      if (!(*this)[i].Equals(other[i])) return false;
    }
    return true;
  }
  template <class OtherElementView, class OtherBufferType>
  bool UncheckedEquals(
      const GenericArrayView<OtherElementView, OtherBufferType, kElementSize,
                             kAddressableUnitSize> &other) const {
    if (ElementCount() != other.ElementCount()) return false;
    for (::std::size_t i = 0; i < ElementCount(); ++i) {
      if (!(*this)[i].UncheckedEquals(other[i])) return false;
    }
    return true;
  }
  bool IsComplete() const { return buffer_.Ok(); }

  template <class Stream>
  bool UpdateFromTextStream(Stream *stream) const {
    return ReadArrayFromTextStream(this, stream);
  }

  template <class Stream>
  void WriteToTextStream(Stream *stream,
                         const TextOutputOptions &options) const {
    WriteArrayToTextStream(this, stream, options);
  }

  static constexpr bool IsAggregate() { return true; }

  BufferType BackingStorage() const { return buffer_; }

  // Forwards to BufferType's ToString(), if any, but only if ElementView is a
  // 1-byte type.
  template <typename String>
  typename ::std::enable_if<kAddressableUnitSize == 8 && kElementSize == 1,
                            String>::type
  ToString() const {
    EMBOSS_CHECK(Ok());
    return BackingStorage().template ToString<String>();
  }

 private:
  // This uses the same technique to select the correct definition of
  // SizeOfBuffer() as in the SizeInBits()/SizeInBytes() selection above.
  template <int N = 0>
  typename ::std::enable_if<((void)N, kAddressableUnitSize == 8),
                            ::std::size_t>::type
  SizeOfBuffer() const {
    return SizeInBytes();
  }
  template <int N = 0>
  typename ::std::enable_if<((void)N, kAddressableUnitSize == 1),
                            ::std::size_t>::type
  SizeOfBuffer() const {
    return SizeInBits();
  }

  // This mess is needed to expand the parameters_ tuple into individual
  // arguments to the ElementView constructor.  If parameters_ has M elements,
  // then:
  //
  // IndexOperatorHelper<false>::ConstructElement() calls
  // IndexOperatorHelper<false, 0>::ConstructElement(), which calls
  // IndexOperatorHelper<false, 0, 1>::ConstructElement(), and so on, up to
  // IndexOperatorHelper<false, 0, 1, ..., M-1>::ConstructElement(), which calls
  // IndexOperatorHelper<true, 0, 1, ..., M>::ConstructElement()
  //
  // That last call will resolve to the second, specialized version of
  // IndexOperatorHelper.  That version's ConstructElement() uses
  // `std::get<N>(parameters)...`, which will be expanded into
  // `std::get<0>(parameters), std::get<1>(parameters), std::get<2>(parameters),
  // ..., std::get<M>(parameters)`.
  //
  // If there are 0 parameters, then operator[]() will call
  // IndexOperatorHelper<true>::ConstructElement(), which still works --
  // `std::get<N>(parameters)...,` will be replaced by ``.
  //
  // In C++14, a lot of this can be replaced by std::index_sequence_of, and in
  // C++17 it can be replaced with std::apply and a lambda.
  //
  // An alternate solution would be to force each parameterized view to have a
  // constructor that accepts a tuple, instead of individual parameters, but
  // that (further) complicates the matrix of constructors for view types.
  template <bool, ::std::size_t... N>
  struct IndexOperatorHelper {
    static ElementView ConstructElement(
        const ::std::tuple<ElementViewParameterTypes...> &parameters,
        BufferType buffer, ::std::size_t index) {
      return IndexOperatorHelper<
          sizeof...(ElementViewParameterTypes) == 1 + sizeof...(N), N...,
          sizeof...(N)>::ConstructElement(parameters, buffer, index);
    }
  };

  template </**/ ::std::size_t... N>
  struct IndexOperatorHelper<true, N...> {
    static ElementView ConstructElement(
        const ::std::tuple<ElementViewParameterTypes...> &parameters,
        BufferType buffer, ::std::size_t index) {
      return ElementView(::std::get<N>(parameters)...,
                         buffer.template GetOffsetStorage<kElementSize, 0>(
                             kElementSize * index, kElementSize));
    }
  };

  ::std::tuple<ElementViewParameterTypes...> parameters_;
  BufferType buffer_;
};

// Optionally prints a shorthand representation of a BitArray in a comment.
template <class ElementView, class BufferType, ::std::size_t kElementSize,
          ::std::size_t kAddressableUnitSize, class Stream>
void WriteShorthandArrayCommentToTextStream(
    const GenericArrayView<ElementView, BufferType, kElementSize,
                           kAddressableUnitSize> *array,
    Stream *stream, const TextOutputOptions &options) {
  // Intentionally empty.  Overload for specific element types.
  // Avoid unused parameters error:
  static_cast<void>(array);
  static_cast<void>(stream);
  static_cast<void>(options);
}

// Prints out the elements of an 8-bit Int or UInt array as characters.
template <class Array, class Stream>
void WriteShorthandAsciiArrayCommentToTextStream(
    const Array *array, Stream *stream, const TextOutputOptions &options) {
  if (!options.multiline()) return;
  if (!options.comments()) return;
  if (array->ElementCount() == 0) return;
  static constexpr int kCharsPerBlock = 64;
  static constexpr char kStandInForNonPrintableChar = '.';
  auto start_new_line = [&]() {
    stream->Write("\n");
    stream->Write(options.current_indent());
    stream->Write("# ");
  };
  for (int i = 0, n = array->ElementCount(); i < n; ++i) {
    const int c = (*array)[i].Read();
    const bool c_is_printable = (c >= 32 && c <= 126);
    const bool starting_new_block = ((i % kCharsPerBlock) == 0);
    if (starting_new_block) start_new_line();
    stream->Write(c_is_printable ? static_cast<char>(c)
                                 : kStandInForNonPrintableChar);
  }
}

// Overload for arrays of UInt.
// Prints out the elements as ASCII characters for arrays of UInt:8.
template <class BufferType, class BitViewType, class Stream,
          ::std::size_t kElementSize, class Parameters,
          class = typename ::std::enable_if<Parameters::kBits == 8>::type>
void WriteShorthandArrayCommentToTextStream(
    const GenericArrayView<prelude::UIntView<Parameters, BitViewType>,
                           BufferType, kElementSize, 8> *array,
    Stream *stream, const TextOutputOptions &options) {
  WriteShorthandAsciiArrayCommentToTextStream(array, stream, options);
}

// Overload for arrays of UInt.
// Prints out the elements as ASCII characters for arrays of Int:8.
template <class BufferType, class BitViewType, class Stream,
          ::std::size_t kElementSize, class Parameters,
          class = typename ::std::enable_if<Parameters::kBits == 8>::type>
void WriteShorthandArrayCommentToTextStream(
    const GenericArrayView<prelude::IntView<Parameters, BitViewType>,
                           BufferType, kElementSize, 8> *array,
    Stream *stream, const TextOutputOptions &options) {
  WriteShorthandAsciiArrayCommentToTextStream(array, stream, options);
}

}  // namespace support
}  // namespace emboss

#endif  // EMBOSS_RUNTIME_CPP_EMBOSS_ARRAY_VIEW_H_
