/*
 * Copyright 2019 The Android Open Source Project
 *
 * 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
 *
 *      http://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.
 */

#include "packet/iterator.h"

#include "os/log.h"

namespace bluetooth {
namespace packet {

template <bool little_endian>
Iterator<little_endian>::Iterator(const std::forward_list<View>& data, size_t offset) {
  data_ = data;
  index_ = offset;
  begin_ = 0;
  end_ = 0;
  for (auto& view : data) {
    end_ += view.size();
  }
}

template <bool little_endian>
Iterator<little_endian> Iterator<little_endian>::operator+(int offset) {
  auto itr(*this);

  return itr += offset;
}

template <bool little_endian>
Iterator<little_endian>& Iterator<little_endian>::operator+=(int offset) {
  index_ += offset;
  return *this;
}

template <bool little_endian>
Iterator<little_endian>& Iterator<little_endian>::operator++() {
  index_++;
  return *this;
}

template <bool little_endian>
Iterator<little_endian> Iterator<little_endian>::operator-(int offset) {
  auto itr(*this);

  return itr -= offset;
}

template <bool little_endian>
int Iterator<little_endian>::operator-(Iterator<little_endian>& itr) {
  return index_ - itr.index_;
}

template <bool little_endian>
Iterator<little_endian>& Iterator<little_endian>::operator-=(int offset) {
  index_ -= offset;

  return *this;
}

template <bool little_endian>
Iterator<little_endian>& Iterator<little_endian>::operator--() {
  if (index_ != 0) index_--;

  return *this;
}

template <bool little_endian>
Iterator<little_endian>& Iterator<little_endian>::operator=(const Iterator<little_endian>& itr) {
  if (this == &itr) return *this;
  this->data_ = itr.data_;
  this->begin_ = itr.begin_;
  this->end_ = itr.end_;
  this->index_ = itr.index_;
  return *this;
}

template <bool little_endian>
bool Iterator<little_endian>::operator==(const Iterator<little_endian>& itr) const {
  return index_ == itr.index_;
}

template <bool little_endian>
bool Iterator<little_endian>::operator!=(const Iterator<little_endian>& itr) const {
  return !(*this == itr);
}

template <bool little_endian>
bool Iterator<little_endian>::operator<(const Iterator<little_endian>& itr) const {
  return index_ < itr.index_;
}

template <bool little_endian>
bool Iterator<little_endian>::operator>(const Iterator<little_endian>& itr) const {
  return index_ > itr.index_;
}

template <bool little_endian>
bool Iterator<little_endian>::operator<=(const Iterator<little_endian>& itr) const {
  return index_ <= itr.index_;
}

template <bool little_endian>
bool Iterator<little_endian>::operator>=(const Iterator<little_endian>& itr) const {
  return index_ >= itr.index_;
}

template <bool little_endian>
uint8_t Iterator<little_endian>::operator*() const {
  ASSERT_LOG(index_ < end_ && !(begin_ > index_), "Index %zu out of bounds: [%zu,%zu)", index_, begin_, end_);
  size_t index = index_;

  for (auto view : data_) {
    if (index < view.size()) {
      return view[index];
    }
    index -= view.size();
  }
  ASSERT_LOG(false, "Out of fragments searching for index %zu", index_);
  return 0;
}

template <bool little_endian>
size_t Iterator<little_endian>::NumBytesRemaining() const {
  if (end_ > index_ && !(begin_ > index_)) {
    return end_ - index_;
  } else {
    return 0;
  }
}

template <bool little_endian>
Iterator<little_endian> Iterator<little_endian>::Subrange(size_t index, size_t length) const {
  Iterator<little_endian> to_return(*this);
  if (to_return.NumBytesRemaining() > index) {
    to_return.index_ = to_return.index_ + index;
    to_return.begin_ = to_return.index_;
    if (to_return.NumBytesRemaining() >= length) {
      to_return.end_ = to_return.index_ + length;
    }
  } else {
    to_return.end_ = 0;
  }

  return to_return;
}

// Explicit instantiations for both types of Iterators.
template class Iterator<true>;
template class Iterator<false>;
}  // namespace packet
}  // namespace bluetooth
