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

#include "core/fxcrt/fixed_size_data_vector.h"

#include <limits>
#include <numeric>
#include <utility>

#include "core/fxcrt/span.h"
#include "core/fxcrt/span_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

TEST(FixedSizedDataVector, NoData) {
  FixedSizeDataVector<int> vec;
  EXPECT_EQ(0u, vec.size());
  EXPECT_TRUE(vec.empty());
  EXPECT_TRUE(vec.span().empty());
}

TEST(FixedSizeDataVector, UninitData) {
  auto vec = FixedSizeDataVector<int>::Uninit(4);
  EXPECT_FALSE(vec.empty());
  ASSERT_EQ(4u, vec.size());
  ASSERT_EQ(4u, vec.span().size());

  constexpr int kData[] = {1, 2, 3, 4};
  fxcrt::spancpy(vec.span(), pdfium::make_span(kData));
  EXPECT_THAT(vec.span(), testing::ElementsAre(1, 2, 3, 4));
}

TEST(FixedSizeDataVector, ZeroedData) {
  auto vec = FixedSizeDataVector<int>::Zeroed(4);
  EXPECT_FALSE(vec.empty());
  EXPECT_EQ(4u, vec.size());
  EXPECT_EQ(4u, vec.span().size());
  EXPECT_THAT(vec.span(), testing::ElementsAre(0, 0, 0, 0));

  constexpr int kData[] = {1, 2, 3, 4};
  fxcrt::spancpy(vec.span(), pdfium::make_span(kData));
  EXPECT_THAT(vec.span(), testing::ElementsAre(1, 2, 3, 4));
}

TEST(FixedSizeDataVector, TryZeroedData) {
  auto vec = FixedSizeDataVector<int>::TryZeroed(4);
  EXPECT_FALSE(vec.empty());
  ASSERT_EQ(4u, vec.size());
  ASSERT_EQ(4u, vec.span().size());
  EXPECT_THAT(vec.span(), testing::ElementsAre(0, 0, 0, 0));

  constexpr int kData[] = {1, 2, 3, 4};
  fxcrt::spancpy(vec.span(), pdfium::make_span(kData));
  EXPECT_THAT(vec.span(), testing::ElementsAre(1, 2, 3, 4));
}

TEST(FixedSizeDataVector, TryAllocFailure) {
  constexpr size_t kCloseToMaxByteAlloc =
      std::numeric_limits<size_t>::max() - 100;
  auto vec = FixedSizeDataVector<int>::TryZeroed(kCloseToMaxByteAlloc);
  EXPECT_TRUE(vec.empty());
  EXPECT_EQ(0u, vec.size());
  EXPECT_EQ(0u, vec.span().size());
}

TEST(FixedSizeDataVector, MoveConstruct) {
  constexpr int kData[] = {1, 2, 3, 4};
  auto vec = FixedSizeDataVector<int>::Uninit(4);
  ASSERT_EQ(4u, vec.span().size());
  fxcrt::spancpy(vec.span(), pdfium::make_span(kData));
  const int* const original_data_ptr = vec.span().data();

  FixedSizeDataVector<int> vec2(std::move(vec));
  EXPECT_FALSE(vec2.empty());
  EXPECT_EQ(4u, vec2.size());
  EXPECT_EQ(4u, vec2.span().size());
  EXPECT_THAT(vec2.span(), testing::ElementsAre(1, 2, 3, 4));
  EXPECT_EQ(vec2.span().data(), original_data_ptr);

  EXPECT_EQ(0u, vec.size());
  EXPECT_TRUE(vec.empty());
  EXPECT_TRUE(vec.span().empty());

  vec = std::move(vec2);
  EXPECT_FALSE(vec.empty());
  EXPECT_EQ(4u, vec.size());
  EXPECT_EQ(4u, vec.span().size());
  EXPECT_THAT(vec.span(), testing::ElementsAre(1, 2, 3, 4));
  EXPECT_EQ(vec.span().data(), original_data_ptr);

  EXPECT_EQ(0u, vec2.size());
  EXPECT_TRUE(vec2.empty());
  EXPECT_TRUE(vec2.span().empty());
}

TEST(FixedSizeDataVector, MoveAssign) {
  auto vec = FixedSizeDataVector<int>();
  auto vec2 = FixedSizeDataVector<int>::Zeroed(4);
  constexpr int kData[] = {1, 2, 3, 4};
  ASSERT_EQ(4u, vec2.span().size());
  fxcrt::spancpy(vec2.span(), pdfium::make_span(kData));

  vec = std::move(vec2);
  EXPECT_TRUE(vec2.empty());
  EXPECT_EQ(4u, vec.span().size());
  EXPECT_THAT(vec.span(), testing::ElementsAre(1, 2, 3, 4));
}

TEST(FixedSizeDataVector, Subspan) {
  auto vec = FixedSizeDataVector<uint32_t>::Uninit(4);
  std::iota(vec.span().begin(), vec.span().end(), 0u);

  pdfium::span<uint32_t> empty = vec.subspan(2, 0);
  EXPECT_TRUE(empty.empty());

  pdfium::span<uint32_t> first = vec.subspan(0, 1);
  ASSERT_EQ(first.size(), 1u);
  EXPECT_EQ(first[0], 0u);

  pdfium::span<uint32_t> mids = vec.subspan(1, 2);
  ASSERT_EQ(mids.size(), 2u);
  EXPECT_EQ(mids[0], 1u);
  EXPECT_EQ(mids[1], 2u);

  pdfium::span<uint32_t> rest = vec.subspan(3);
  ASSERT_EQ(rest.size(), 1u);
  EXPECT_EQ(rest[0], 3u);
}

TEST(FixedSizeDataVector, First) {
  auto vec = FixedSizeDataVector<uint32_t>::Uninit(4);
  std::iota(vec.span().begin(), vec.span().end(), 0u);

  pdfium::span<uint32_t> empty = vec.first(0);
  EXPECT_TRUE(empty.empty());

  pdfium::span<uint32_t> some = vec.first(2);
  ASSERT_EQ(some.size(), 2u);
  EXPECT_EQ(some[0], 0u);
  EXPECT_EQ(some[1], 1u);
}

TEST(FixedSizeDataVector, Last) {
  auto vec = FixedSizeDataVector<uint32_t>::Uninit(4);
  std::iota(vec.span().begin(), vec.span().end(), 0u);

  pdfium::span<uint32_t> empty = vec.first(0);
  EXPECT_TRUE(empty.empty());

  pdfium::span<uint32_t> some = vec.first(2);
  ASSERT_EQ(some.size(), 2u);
  EXPECT_EQ(some[0], 0u);
  EXPECT_EQ(some[1], 1u);
}
