// Copyright 2025 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.

#include "pw_containers/ptr_iterator.h"

#include <array>
#include <iterator>
#include <type_traits>

#include "pw_unit_test/framework.h"

namespace {

// Create a fake container for use with PtrIterator.
class FakeVector {
 public:
  using value_type = int;
  using reference = int&;
  using const_reference = const int&;
  using pointer = int*;
  using const_pointer = const int*;
  using iterator = pw::containers::PtrIterator<FakeVector>;
  using const_iterator = pw::containers::ConstPtrIterator<FakeVector>;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

  constexpr FakeVector(int* data, size_t length)
      : data_(data), length_(length) {}

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

  reverse_iterator rbegin() { return reverse_iterator(end()); }
  reverse_iterator rend() { return reverse_iterator(begin()); }
  const_reverse_iterator rbegin() const {
    return const_reverse_iterator(end());
  }
  const_reverse_iterator rend() const {
    return const_reverse_iterator(begin());
  }

 private:
  int* data_;
  size_t length_;
};

static_assert(std::is_same_v<std::iterator_traits<pw::containers::PtrIterator<
                                 FakeVector>>::iterator_category,
                             pw::containers::contiguous_iterator_tag>);
static_assert(
    std::is_same_v<std::iterator_traits<pw::containers::ConstPtrIterator<
                       FakeVector>>::iterator_category,
                   pw::containers::contiguous_iterator_tag>);

static_assert(!std::is_convertible_v<FakeVector::iterator, int*>);
static_assert(!std::is_convertible_v<int*, FakeVector::iterator>);
static_assert(
    std::is_convertible_v<FakeVector::iterator, FakeVector::const_iterator>);
static_assert(
    !std::is_convertible_v<FakeVector::const_iterator, FakeVector::iterator>);

TEST(PtrIterator, DefaultConstructor) {
  pw::containers::PtrIterator<FakeVector> it;
  pw::containers::ConstPtrIterator<FakeVector> cit;
  EXPECT_EQ(it, pw::containers::PtrIterator<FakeVector>());
  EXPECT_EQ(cit, pw::containers::ConstPtrIterator<FakeVector>());
}

TEST(PtrIterator, IterateForwards) {
  std::array<int, 5> data{1, 2, 3, 4, 5};
  FakeVector vec(data.data(), data.size());
  int expected = 1;
  for (int val : vec) {
    EXPECT_EQ(val, expected++);
  }

  std::array<int, 3> data2{10, 20, 30};
  FakeVector vec2(data2.data(), data2.size());
  expected = 10;
  for (int val : vec2) {
    EXPECT_EQ(val, expected);
    expected += 10;
  }
}

TEST(PtrIterator, ReverseIterate) {
  std::array<int, 5> data{1, 2, 3, 4, 5};
  FakeVector vec(data.data(), data.size());
  int expected = 5;
  for (FakeVector::reverse_iterator it = vec.rbegin(); it != vec.rend(); ++it) {
    EXPECT_EQ(*it, expected--);
  }

  const FakeVector& cvec = vec;
  expected = 5;
  for (FakeVector::const_reverse_iterator it = cvec.rbegin(); it != cvec.rend();
       ++it) {
    EXPECT_EQ(*it, expected--);
  }
}

TEST(PtrIterator, IterateBackwards) {
  std::array<int, 5> data{1, 2, 3, 4, 5};
  FakeVector vec(data.data(), data.size());
  FakeVector::iterator it = vec.end();
  int expected = 5;
  do {
    --it;
    EXPECT_EQ(*it, expected--);
  } while (it != vec.begin());

  std::array<int, 2> data2{100, 200};
  FakeVector vec2(data2.data(), data2.size());
  FakeVector::iterator it2 = vec2.end();
  int expected2 = 200;
  do {
    --it2;
    EXPECT_EQ(*it2, expected2);
    expected2 -= 100;
  } while (it2 != vec2.begin());
}

TEST(PtrIterator, PostIncrement) {
  std::array<int, 2> data{1, 2};
  FakeVector vec(data.data(), data.size());
  FakeVector::iterator it = vec.begin();
  EXPECT_EQ(*(it++), 1);
  EXPECT_EQ(*it, 2);
}

TEST(PtrIterator, PreIncrement) {
  std::array<int, 3> data{1, 2, 3};
  FakeVector vec(data.data(), data.size());
  FakeVector::iterator it = vec.begin();
  EXPECT_EQ(*(++it), 2);
  EXPECT_EQ(*it, 2);
}

TEST(PtrIterator, PostDecrement) {
  std::array<int, 4> data{1, 2, 3, 4};
  FakeVector vec(data.data(), data.size());
  FakeVector::iterator it = vec.end();
  --it;
  EXPECT_EQ(*(it--), 4);
  EXPECT_EQ(*it, 3);
}

TEST(PtrIterator, PreDecrement) {
  std::array<int, 5> data{1, 2, 3, 4, 5};
  FakeVector vec(data.data(), data.size());
  FakeVector::iterator it = vec.end();
  --it;
  EXPECT_EQ(*(--it), 4);
  EXPECT_EQ(*it, 4);
}

TEST(PtrIterator, Addition) {
  std::array<int, 6> data{1, 2, 3, 4, 5, 6};
  FakeVector vec(data.data(), data.size());
  FakeVector::iterator it = vec.begin();
  EXPECT_EQ(*(it + 2), 3);
  EXPECT_EQ(*(2 + it), 3);
  it += 4;
  EXPECT_EQ(*it, 5);
}

TEST(PtrIterator, Subtraction) {
  std::array<int, 7> data{1, 2, 3, 4, 5, 6, 7};
  FakeVector vec(data.data(), data.size());
  FakeVector::iterator it = vec.end();
  EXPECT_EQ(*(it - 2), 6);
  it -= 3;
  EXPECT_EQ(*it, 5);
}

TEST(PtrIterator, Difference) {
  std::array<int, 8> data{1, 2, 3, 4, 5, 6, 7, 8};
  FakeVector vec(data.data(), data.size());
  EXPECT_EQ(vec.end() - vec.begin(), 8);

  std::array<int, 1> data2{1};
  FakeVector vec2(data2.data(), data2.size());
  EXPECT_EQ(vec2.end() - vec2.begin(), 1);
}

TEST(PtrIterator, Comparison) {
  std::array<int, 5> data{1, 2, 3, 4, 5};
  FakeVector vec(data.data(), data.size());
  FakeVector::iterator it1 = vec.begin();
  FakeVector::iterator it2 = vec.begin();
  EXPECT_TRUE(it1 == it2);
  EXPECT_FALSE(it1 != it2);
  EXPECT_FALSE(it1 < it2);
  EXPECT_TRUE(it1 <= it2);
  EXPECT_FALSE(it1 > it2);
  EXPECT_TRUE(it1 >= it2);

  ++it2;
  EXPECT_FALSE(it1 == it2);
  EXPECT_TRUE(it1 != it2);
  EXPECT_TRUE(it1 < it2);
  EXPECT_TRUE(it1 <= it2);
  EXPECT_FALSE(it1 > it2);
  EXPECT_FALSE(it1 >= it2);
}

TEST(PtrIterator, ConstConversion) {
  std::array<int, 5> data{1, 2, 3, 4, 5};
  FakeVector vec(data.data(), data.size());
  FakeVector::iterator it = vec.begin();
  FakeVector::const_iterator cit = it;
  EXPECT_EQ(*it, *cit);
}

TEST(PtrIterator, ArrayAccess) {
  std::array<int, 4> data{1, 2, 3, 4};
  FakeVector vec(data.data(), data.size());
  FakeVector::iterator it = vec.begin();
  EXPECT_EQ(it[2], 3);
  EXPECT_EQ(it[0], 1);
  EXPECT_EQ(it[3], 4);
}

}  // namespace
