// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/containers/vector_buffer.h"

#include "base/compiler_specific.h"
#include "base/memory/raw_ptr.h"
#include "base/test/bind.h"
#include "base/test/copy_only_int.h"
#include "base/test/move_only_int.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base::internal {

namespace {

class TRIVIAL_ABI TrivialAbiWithCountingOperations {
 public:
  TrivialAbiWithCountingOperations(int* destruction_counter, int* move_counter)
      : destruction_counter_(destruction_counter),
        move_counter_(move_counter) {}

  ~TrivialAbiWithCountingOperations() { ++*destruction_counter_; }

  // Copy construction and assignment should not be used.
  TrivialAbiWithCountingOperations(const TrivialAbiWithCountingOperations&) =
      delete;
  TrivialAbiWithCountingOperations& operator=(
      const TrivialAbiWithCountingOperations&) = delete;

  // Count how many times the move constructor is used.
  TrivialAbiWithCountingOperations(TrivialAbiWithCountingOperations&& rhs)
      : destruction_counter_(rhs.destruction_counter_),
        move_counter_(rhs.move_counter_) {
    ++*move_counter_;
  }

  // Move assignment should not be used.
  TrivialAbiWithCountingOperations& operator=(
      TrivialAbiWithCountingOperations&&) = delete;

 private:
  raw_ptr<int> destruction_counter_;
  raw_ptr<int> move_counter_;
};

}  // namespace

TEST(VectorBuffer, DeletePOD) {
  constexpr int size = 10;
  VectorBuffer<int> buffer(size);
  for (int i = 0; i < size; i++) {
    buffer[i] = i + 1;
  }

  VectorBuffer<int>::DestructRange(buffer.as_span());

  // Delete should do nothing.
  for (int i = 0; i < size; i++) {
    EXPECT_EQ(i + 1, buffer[i]);
  }
}

TEST(VectorBuffer, DeleteMoveOnly) {
  constexpr int size = 10;
  VectorBuffer<MoveOnlyInt> buffer(size);
  for (int i = 0; i < size; i++) {
    // SAFETY: `i < size`, and `size` is the buffer's allocation size, so
    // `begin() + i` is inside the buffer.
    new (UNSAFE_BUFFERS(buffer.begin() + i)) MoveOnlyInt(i + 1);
  }

  std::vector<int> destroyed_instances;
  auto scoped_callback_cleanup =
      MoveOnlyInt::SetScopedDestructionCallback(BindLambdaForTesting(
          [&](int value) { destroyed_instances.push_back(value); }));
  VectorBuffer<MoveOnlyInt>::DestructRange(buffer.as_span());

  EXPECT_THAT(destroyed_instances,
              ::testing::ElementsAre(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
}

TEST(VectorBuffer, PODMove) {
  constexpr int size = 10;
  VectorBuffer<int> dest(size);

  VectorBuffer<int> original(size);
  for (int i = 0; i < size; i++) {
    original[i] = i + 1;
  }

  VectorBuffer<int>::MoveConstructRange(original.as_span(), dest.as_span());
  for (int i = 0; i < size; i++) {
    EXPECT_EQ(i + 1, dest[i]);
  }
}

TEST(VectorBuffer, MovableMove) {
  constexpr int size = 10;
  VectorBuffer<MoveOnlyInt> dest(size);

  VectorBuffer<MoveOnlyInt> original(size);
  for (int i = 0; i < size; i++) {
    // SAFETY: `i < size`, and `size` is the buffer's allocation size, so
    // `begin() + i` is inside the buffer.
    new (UNSAFE_BUFFERS(original.begin() + i)) MoveOnlyInt(i + 1);
  }

  std::vector<int> destroyed_instances;
  auto scoped_callback_cleanup =
      MoveOnlyInt::SetScopedDestructionCallback(BindLambdaForTesting(
          [&](int value) { destroyed_instances.push_back(value); }));
  VectorBuffer<MoveOnlyInt>::MoveConstructRange(original.as_span(),
                                                dest.as_span());

  for (int i = 0; i < size; i++) {
    EXPECT_EQ(i + 1, dest[i].data());
  }
  // The original values were consumed, so when the original elements are
  // destroyed, the destruction callback should report 0.
  EXPECT_THAT(destroyed_instances,
              ::testing::ElementsAre(0, 0, 0, 0, 0, 0, 0, 0, 0, 0));
}

TEST(VectorBuffer, CopyToMove) {
  constexpr int size = 10;
  VectorBuffer<CopyOnlyInt> dest(size);

  VectorBuffer<CopyOnlyInt> original(size);
  for (int i = 0; i < size; i++) {
    // SAFETY: `i < size`, and `size` is the buffer's allocation size, so
    // `begin() + i` is inside the buffer.
    new (UNSAFE_BUFFERS(original.begin() + i)) CopyOnlyInt(i + 1);
  }

  std::vector<int> destroyed_instances;
  auto scoped_callback_cleanup =
      CopyOnlyInt::SetScopedDestructionCallback(BindLambdaForTesting(
          [&](int value) { destroyed_instances.push_back(value); }));
  VectorBuffer<CopyOnlyInt>::MoveConstructRange(original.as_span(),
                                                dest.as_span());

  for (int i = 0; i < size; i++) {
    EXPECT_EQ(i + 1, dest[i].data());
  }

  EXPECT_THAT(destroyed_instances,
              ::testing::ElementsAre(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
}

TEST(VectorBuffer, TrivialAbiMove) {
  // Currently trivial relocation doesn't work on Windows for some reason, so
  // the test needs to handle both cases.
  constexpr bool kHaveTrivialRelocation =
      IS_TRIVIALLY_RELOCATABLE(TrivialAbiWithCountingOperations);
  constexpr int size = 10;
  VectorBuffer<TrivialAbiWithCountingOperations> dest(size);

  int destruction_count = 0;
  int move_count = 0;
  VectorBuffer<TrivialAbiWithCountingOperations> original(size);
  for (int i = 0; i < size; i++) {
    // SAFETY: `i < size`, and `size` is the buffer's allocation size, so
    // `begin() + i` is inside the buffer.
    new (UNSAFE_BUFFERS(original.begin() + i))
        TrivialAbiWithCountingOperations(&destruction_count, &move_count);
  }

  VectorBuffer<TrivialAbiWithCountingOperations>::MoveConstructRange(
      original.as_span(), dest.as_span());

  // We expect the move to have been performed via memcpy, without calling move
  // constructors or destructors.
  EXPECT_EQ(destruction_count, kHaveTrivialRelocation ? 0 : size);
  EXPECT_EQ(move_count, kHaveTrivialRelocation ? 0 : size);

  dest.DestructRange(dest.as_span());
  EXPECT_EQ(destruction_count, kHaveTrivialRelocation ? size : size * 2);
  EXPECT_EQ(move_count, kHaveTrivialRelocation ? 0 : size);
}

}  // namespace base::internal
