// Copyright (c) 2016 Google Inc.
//
// 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 <memory>
#include <vector>

#include "gmock/gmock.h"

#include "source/opt/iterator.h"
#include "source/opt/make_unique.h"

namespace spvtools {
namespace opt {
namespace {

using ::testing::ContainerEq;

TEST(Iterator, IncrementDeref) {
  const int count = 100;
  std::vector<std::unique_ptr<int>> data;
  for (int i = 0; i < count; ++i) {
    data.emplace_back(new int(i));
  }

  UptrVectorIterator<int> it(&data, data.begin());
  UptrVectorIterator<int> end(&data, data.end());

  EXPECT_EQ(*data[0], *it);
  for (int i = 1; i < count; ++i) {
    EXPECT_NE(end, it);
    EXPECT_EQ(*data[i], *(++it));
  }
  EXPECT_EQ(end, ++it);
}

TEST(Iterator, DecrementDeref) {
  const int count = 100;
  std::vector<std::unique_ptr<int>> data;
  for (int i = 0; i < count; ++i) {
    data.emplace_back(new int(i));
  }

  UptrVectorIterator<int> begin(&data, data.begin());
  UptrVectorIterator<int> it(&data, data.end());

  for (int i = count - 1; i >= 0; --i) {
    EXPECT_NE(begin, it);
    EXPECT_EQ(*data[i], *(--it));
  }
  EXPECT_EQ(begin, it);
}

TEST(Iterator, PostIncrementDeref) {
  const int count = 100;
  std::vector<std::unique_ptr<int>> data;
  for (int i = 0; i < count; ++i) {
    data.emplace_back(new int(i));
  }

  UptrVectorIterator<int> it(&data, data.begin());
  UptrVectorIterator<int> end(&data, data.end());

  for (int i = 0; i < count; ++i) {
    EXPECT_NE(end, it);
    EXPECT_EQ(*data[i], *(it++));
  }
  EXPECT_EQ(end, it);
}

TEST(Iterator, PostDecrementDeref) {
  const int count = 100;
  std::vector<std::unique_ptr<int>> data;
  for (int i = 0; i < count; ++i) {
    data.emplace_back(new int(i));
  }

  UptrVectorIterator<int> begin(&data, data.begin());
  UptrVectorIterator<int> end(&data, data.end());
  UptrVectorIterator<int> it(&data, data.end());

  EXPECT_EQ(end, it--);
  for (int i = count - 1; i >= 1; --i) {
    EXPECT_EQ(*data[i], *(it--));
  }
  // Decrementing .begin() is undefined behavior.
  EXPECT_EQ(*data[0], *it);
}

TEST(Iterator, Access) {
  const int count = 100;
  std::vector<std::unique_ptr<int>> data;
  for (int i = 0; i < count; ++i) {
    data.emplace_back(new int(i));
  }

  UptrVectorIterator<int> it(&data, data.begin());

  for (int i = 0; i < count; ++i) EXPECT_EQ(*data[i], it[i]);
}

TEST(Iterator, Comparison) {
  const int count = 100;
  std::vector<std::unique_ptr<int>> data;
  for (int i = 0; i < count; ++i) {
    data.emplace_back(new int(i));
  }

  UptrVectorIterator<int> it(&data, data.begin());
  UptrVectorIterator<int> end(&data, data.end());

  for (int i = 0; i < count; ++i, ++it) EXPECT_TRUE(it < end);
  EXPECT_EQ(end, it);
}

TEST(Iterator, InsertBeginEnd) {
  const int count = 100;

  std::vector<std::unique_ptr<int>> data;
  std::vector<int> expected;
  std::vector<int> actual;

  for (int i = 0; i < count; ++i) {
    data.emplace_back(new int(i));
    expected.push_back(i);
  }

  // Insert at the beginning
  expected.insert(expected.begin(), -100);
  UptrVectorIterator<int> begin(&data, data.begin());
  auto insert_point = begin.InsertBefore(MakeUnique<int>(-100));
  for (int i = 0; i < count + 1; ++i) {
    actual.push_back(*(insert_point++));
  }
  EXPECT_THAT(actual, ContainerEq(expected));

  // Insert at the end
  expected.push_back(-42);
  expected.push_back(-36);
  expected.push_back(-77);
  UptrVectorIterator<int> end(&data, data.end());
  end = end.InsertBefore(MakeUnique<int>(-77));
  end = end.InsertBefore(MakeUnique<int>(-36));
  end = end.InsertBefore(MakeUnique<int>(-42));

  actual.clear();
  begin = UptrVectorIterator<int>(&data, data.begin());
  for (int i = 0; i < count + 4; ++i) {
    actual.push_back(*(begin++));
  }
  EXPECT_THAT(actual, ContainerEq(expected));
}

TEST(Iterator, InsertMiddle) {
  const int count = 100;

  std::vector<std::unique_ptr<int>> data;
  std::vector<int> expected;
  std::vector<int> actual;

  for (int i = 0; i < count; ++i) {
    data.emplace_back(new int(i));
    expected.push_back(i);
  }

  const int insert_pos = 42;
  expected.insert(expected.begin() + insert_pos, -100);
  expected.insert(expected.begin() + insert_pos, -42);

  UptrVectorIterator<int> it(&data, data.begin());
  for (int i = 0; i < insert_pos; ++i) ++it;
  it = it.InsertBefore(MakeUnique<int>(-100));
  it = it.InsertBefore(MakeUnique<int>(-42));
  auto begin = UptrVectorIterator<int>(&data, data.begin());
  for (int i = 0; i < count + 2; ++i) {
    actual.push_back(*(begin++));
  }
  EXPECT_THAT(actual, ContainerEq(expected));
}

TEST(IteratorRange, Interface) {
  const uint32_t count = 100;

  std::vector<std::unique_ptr<uint32_t>> data;

  for (uint32_t i = 0; i < count; ++i) {
    data.emplace_back(new uint32_t(i));
  }

  auto b = UptrVectorIterator<uint32_t>(&data, data.begin());
  auto e = UptrVectorIterator<uint32_t>(&data, data.end());
  auto range = IteratorRange<decltype(b)>(b, e);

  EXPECT_EQ(b, range.begin());
  EXPECT_EQ(e, range.end());
  EXPECT_FALSE(range.empty());
  EXPECT_EQ(count, range.size());
  EXPECT_EQ(0u, *range.begin());
  EXPECT_EQ(99u, *(--range.end()));

  // IteratorRange itself is immutable.
  ++b, --e;
  EXPECT_EQ(count, range.size());
  ++range.begin(), --range.end();
  EXPECT_EQ(count, range.size());
}

TEST(Iterator, FilterIterator) {
  struct Placeholder {
    int val;
  };
  std::vector<Placeholder> data = {{1}, {2}, {3}, {4}, {5},
                                   {6}, {7}, {8}, {9}, {10}};

  // Predicate to only consider odd values.
  struct Predicate {
    bool operator()(const Placeholder& data) { return data.val % 2; }
  };
  Predicate pred;

  auto filter_range = MakeFilterIteratorRange(data.begin(), data.end(), pred);

  EXPECT_EQ(filter_range.begin().Get(), data.begin());
  EXPECT_EQ(filter_range.end(), filter_range.begin().GetEnd());

  for (Placeholder& data : filter_range) {
    EXPECT_EQ(data.val % 2, 1);
  }

  for (auto it = filter_range.begin(); it != filter_range.end(); it++) {
    EXPECT_EQ(it->val % 2, 1);
    EXPECT_EQ((*it).val % 2, 1);
  }

  for (auto it = filter_range.begin(); it != filter_range.end(); ++it) {
    EXPECT_EQ(it->val % 2, 1);
    EXPECT_EQ((*it).val % 2, 1);
  }

  EXPECT_EQ(MakeFilterIterator(data.begin(), data.end(), pred).Get(),
            data.begin());
  EXPECT_EQ(MakeFilterIterator(data.end(), data.end(), pred).Get(), data.end());
  EXPECT_EQ(MakeFilterIterator(data.begin(), data.end(), pred).GetEnd(),
            MakeFilterIterator(data.end(), data.end(), pred));
  EXPECT_NE(MakeFilterIterator(data.begin(), data.end(), pred),
            MakeFilterIterator(data.end(), data.end(), pred));

  // Empty range: no values satisfies the predicate.
  auto empty_range = MakeFilterIteratorRange(
      data.begin(), data.end(),
      [](const Placeholder& data) { return data.val > 10; });
  EXPECT_EQ(empty_range.begin(), empty_range.end());
}

}  // namespace
}  // namespace opt
}  // namespace spvtools
