/*
 * Copyright (C) 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 "perfetto/base/circular_queue.h"

#include <random>

#include "gtest/gtest.h"

namespace perfetto {
namespace base {
namespace {

TEST(CircularQueueTest, Int) {
  CircularQueue<int> queue(/*initial_capacity=*/1);
  ASSERT_EQ(queue.size(), 0u);
  queue.emplace_back(101);
  ASSERT_EQ(queue.size(), 1u);
  queue.emplace_back(102);
  queue.emplace_back(103);
  queue.emplace_back(104);
  ASSERT_EQ(queue.size(), 4u);

  auto it = queue.begin();
  for (int i = 101; i <= 104; i++) {
    ASSERT_EQ(*it, i);
    it++;
  }
  ASSERT_EQ(it, queue.end());

  queue.erase_front(1);
  ASSERT_EQ(queue.size(), 3u);
  ASSERT_EQ(*queue.begin(), 102);

  *(queue.begin() + 1) = 42;
  ASSERT_EQ(*(queue.end() - 2), 42);

  queue.erase_front(2);
  ASSERT_EQ(queue.size(), 1u);
  ASSERT_EQ(*queue.begin(), 104);

  queue.pop_front();
  ASSERT_EQ(queue.size(), 0u);
  ASSERT_EQ(queue.begin(), queue.end());

  const size_t kNumInts = 100000u;

  {
    std::minstd_rand0 rnd_engine(0);
    for (size_t i = 0; i < kNumInts; i++) {
      int n = static_cast<int>(rnd_engine());
      queue.emplace_back(n);
    }
  }
  ASSERT_EQ(queue.size(), kNumInts);
  ASSERT_EQ(static_cast<size_t>(queue.end() - queue.begin()), kNumInts);
  {
    std::minstd_rand0 rnd_engine(0);
    it = queue.begin();
    for (size_t i = 0; i < kNumInts; ++i, ++it) {
      ASSERT_LT(it, queue.end());
      ASSERT_EQ(*it, static_cast<int>(rnd_engine()));
    }
  }

  {
    std::minstd_rand0 del_rnd(42);
    std::minstd_rand0 rnd_engine(0);
    while (!queue.empty()) {
      ASSERT_EQ(*queue.begin(), static_cast<int>(rnd_engine()));
      size_t num_del = (del_rnd() % 8) + 1;
      queue.erase_front(num_del + 1);  // +1 because of the read 2 lines above.
      rnd_engine.discard(num_del);
    }
  }
}

TEST(CircularQueueTest, Sorting) {
  CircularQueue<uint64_t> queue;
  std::minstd_rand0 rnd_engine(0);
  for (int i = 0; i < 100000; i++) {
    queue.emplace_back(static_cast<uint64_t>(rnd_engine()));
    if ((i % 100) == 0)
      queue.erase_front(29);
  }
  ASSERT_FALSE(std::is_sorted(queue.begin(), queue.end()));
  std::sort(queue.begin(), queue.end());
  ASSERT_TRUE(std::is_sorted(queue.begin(), queue.end()));
}

TEST(CircularQueueTest, MoveOperators) {
  CircularQueue<int> queue;
  queue.emplace_back(1);
  queue.emplace_back(2);

  {
    CircularQueue<int> moved(std::move(queue));
    ASSERT_TRUE(queue.empty());
    ASSERT_EQ(moved.size(), 2u);

    moved.emplace_back(3);
    moved.emplace_back(4);
    ASSERT_EQ(moved.size(), 4u);
  }
  queue.emplace_back(10);
  queue.emplace_back(11);
  queue.emplace_back(12);
  ASSERT_EQ(queue.size(), 3u);
  ASSERT_EQ(queue.front(), 10);
  ASSERT_EQ(queue.back(), 12);

  {
    CircularQueue<int> moved;
    moved.emplace_back(42);
    moved = std::move(queue);
    ASSERT_TRUE(queue.empty());
    ASSERT_EQ(moved.size(), 3u);
    ASSERT_EQ(moved.size(), 3u);
    ASSERT_EQ(moved.front(), 10);
    ASSERT_EQ(moved.back(), 12);
  }
}

TEST(CircularQueueTest, Iterators) {
  for (size_t repeat = 1; repeat < 8; repeat++) {
    size_t capacity = 8 * (1 << repeat);
    CircularQueue<size_t> queue(capacity);
    for (size_t i = 0; i < capacity - 2; i++)
      queue.emplace_back(0u);
    queue.erase_front(queue.size());
    ASSERT_TRUE(queue.empty());
    ASSERT_EQ(queue.capacity(), capacity);

    // Now the queue is empty and the internal write iterator is abut to wrap.

    // Add a bit more than half-capacity and check that the queue didn't resize.
    for (size_t i = 0; i < capacity / 2 + 3; i++)
      queue.emplace_back(i);
    ASSERT_EQ(queue.capacity(), capacity);

    // Check that all iterators are consistent.
    auto begin = queue.begin();
    auto end = queue.end();
    auto mid = begin + std::distance(begin, end) / 2;
    ASSERT_TRUE(std::is_sorted(begin, end));
    ASSERT_TRUE(begin < end);
    ASSERT_TRUE(begin <= begin);
    ASSERT_TRUE(begin >= begin);
    ASSERT_FALSE(begin < begin);
    ASSERT_FALSE(begin > begin);
    ASSERT_TRUE(begin + 1 > begin);
    ASSERT_TRUE(begin + 1 >= begin);
    ASSERT_FALSE(begin >= begin + 1);
    ASSERT_TRUE(begin <= begin);
    ASSERT_TRUE(begin <= begin + 1);
    ASSERT_TRUE(end > mid);
    ASSERT_TRUE(mid > begin);
    ASSERT_TRUE(std::is_sorted(begin, mid));
    ASSERT_TRUE(std::is_sorted(mid, end));
  }
}

TEST(CircularQueueTest, ObjectLifetime) {
  class Checker {
   public:
    struct Stats {
      int num_ctors = 0;
      int num_dtors = 0;
      int num_alive = 0;
    };
    Checker(Stats* stats, int n) : stats_(stats), n_(n) {
      EXPECT_GE(n, 0);
      stats_->num_ctors++;
      stats_->num_alive++;
      ptr_ = reinterpret_cast<uintptr_t>(this);
    }

    ~Checker() {
      EXPECT_EQ(ptr_, reinterpret_cast<uintptr_t>(this));
      if (n_ >= 0)
        stats_->num_alive--;
      n_ = -1;
      stats_->num_dtors++;
    }

    Checker(Checker&& other) noexcept {
      n_ = other.n_;
      other.n_ = -1;
      stats_ = other.stats_;
      ptr_ = reinterpret_cast<uintptr_t>(this);
    }

    Checker& operator=(Checker&& other) {
      new (this) Checker(std::move(other));
      return *this;
    }

    Checker(const Checker&) = delete;
    Checker& operator=(const Checker&) = delete;

    Stats* stats_ = nullptr;
    uintptr_t ptr_ = 0;
    int n_ = -1;
  };

  // Check that dtors are invoked on old elements when growing capacity.
  Checker::Stats stats;
  {
    CircularQueue<Checker> queue(/*initial_capacity=*/2);
    for (int i = 0; i < 2; i++)
      queue.emplace_back(&stats, i);
    ASSERT_EQ(stats.num_ctors, 2);
    ASSERT_EQ(stats.num_dtors, 0);

    // This further insertion will grow the queue, causing two std::move()s
    // for the previous elements and one emplace.
    queue.emplace_back(&stats, 2);
    ASSERT_EQ(stats.num_ctors, 3);

    // The two old elements that have std::move()d should be destroyed upon
    // expansion.
    ASSERT_EQ(stats.num_dtors, 2);
  }
  ASSERT_EQ(stats.num_dtors, 2 + 3);

  stats = Checker::Stats();
  {
    CircularQueue<Checker> queue(/*initial_capacity=*/1);
    for (int i = 0; i < 5; i++)
      queue.emplace_back(&stats, i);
    ASSERT_EQ(stats.num_ctors, 5);
    Checker c5(&stats, 5);
    queue.emplace_back(std::move(c5));
    ASSERT_EQ(stats.num_alive, 5 + 1);

    queue.erase_front(2);
    ASSERT_EQ(stats.num_alive, 5 + 1 - 2);

    for (int i = 0; i < 4; i++)
      queue.emplace_back(&stats, 10 + i);
    ASSERT_EQ(stats.num_alive, 5 + 1 - 2 + 4);
  }
  ASSERT_EQ(stats.num_ctors, 5 + 1 + 4);
  ASSERT_EQ(stats.num_alive, 0);

  stats = Checker::Stats();
  {
    CircularQueue<Checker> q1(1);
    CircularQueue<Checker> q2(64);
    for (int i = 0; i < 100; i++) {
      q1.emplace_back(&stats, 1000 + i * 2);
      q2.emplace_back(&stats, 1001 + i * 2);
    }

    ASSERT_EQ(stats.num_alive, 200);

    for (int i = 0; i < 100; i += 2) {
      auto it1 = q1.begin() + i;
      auto it2 = q2.begin() + i;
      std::swap(*it1, *it2);
    }
    auto comparer = [](const Checker& lhs, const Checker& rhs) {
      return lhs.n_ < rhs.n_;
    };
    ASSERT_TRUE(std::is_sorted(q1.begin(), q1.end(), comparer));
    ASSERT_TRUE(std::is_sorted(q2.begin(), q2.end(), comparer));
    ASSERT_EQ(stats.num_alive, 200);
  }
}

}  // namespace
}  // namespace base
}  // namespace perfetto
