// Copyright (c) 2026 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "quiche/common/stable_block_list.h"

#include <memory>
#include <vector>

#include "quiche/common/platform/api/quiche_test.h"

namespace quiche {
namespace {

struct AllocStats {
  size_t allocs = 0;
  size_t deallocs = 0;
};

template <typename T>
struct TrackingAllocator {
  using value_type = T;

  std::shared_ptr<AllocStats> stats;

  TrackingAllocator() = default;
  explicit TrackingAllocator(std::shared_ptr<AllocStats> s)
      : stats(std::move(s)) {}

  template <typename U>
  TrackingAllocator(const TrackingAllocator<U>& other) : stats(other.stats) {}

  T* allocate(std::size_t n) {
    if (stats) stats->allocs++;
    return std::allocator<T>().allocate(n);
  }

  void deallocate(T* p, std::size_t n) {
    if (stats) stats->deallocs++;
    std::allocator<T>().deallocate(p, n);
  }

  template <typename U>
  bool operator==(const TrackingAllocator<U>& other) const {
    return stats == other.stats;
  }
  template <typename U>
  bool operator!=(const TrackingAllocator<U>& other) const {
    return stats != other.stats;
  }
};

TEST(StableBlockListTest, BasicOps) {
  StableBlockList<int> list;
  EXPECT_TRUE(list.empty());
  EXPECT_EQ(list.size(), 0);

  list.push_back(1);
  list.push_back(2);
  list.push_back(3);

  EXPECT_FALSE(list.empty());
  EXPECT_EQ(list.size(), 3);
  EXPECT_EQ(list.front(), 1);
  EXPECT_EQ(list.back(), 3);

  StableBlockList<int> list2 = std::move(list);
  EXPECT_FALSE(list2.empty());
  EXPECT_EQ(list2.size(), 3);
  EXPECT_EQ(list2.front(), 1);
  EXPECT_EQ(list2.back(), 3);

  list2.clear();
  EXPECT_TRUE(list2.empty());
  EXPECT_EQ(list2.size(), 0);
}

TEST(StableBlockListTest, Traversal) {
  StableBlockList<int> list;
  list.push_back(1);
  list.push_back(2);
  list.push_back(3);

  auto it = list.begin();
  EXPECT_EQ(*it, 1);
  ++it;
  EXPECT_EQ(*it, 2);
  ++it;
  EXPECT_EQ(*it, 3);
  ++it;
  EXPECT_TRUE(it == list.end());

  --it;
  EXPECT_EQ(*it, 3);
  --it;
  EXPECT_EQ(*it, 2);
  --it;
  EXPECT_EQ(*it, 1);
  EXPECT_TRUE(it == list.begin());
}

TEST(StableBlockListTest, IteratorStabilityOnPushBack) {
  StableBlockList<int, 4>
      list;  // Small capacity to force multi-block allocations
  // Fill one chunk (4 elements)
  for (int i = 0; i < 4; ++i) {
    list.push_back(i * 10);  // 0, 10, 20, 30
  }

  // Store iterators
  std::vector<StableBlockList<int, 4>::iterator> iters;
  for (auto it = list.begin(); it != list.end(); ++it) {
    iters.push_back(it);
  }

  // Push back more elements to force allocation of a new block
  list.push_back(40);
  list.push_back(50);

  EXPECT_EQ(list.size(), 6);

  // Verify stored iterators are still valid and point to the same values
  EXPECT_EQ(*iters[0], 0);
  EXPECT_EQ(*iters[1], 10);
  EXPECT_EQ(*iters[2], 20);
  EXPECT_EQ(*iters[3], 30);

  // Verify traversal order
  std::vector<int> elements;
  for (int x : list) {
    elements.push_back(x);
  }
  EXPECT_THAT(elements, ::testing::ElementsAre(0, 10, 20, 30, 40, 50));
}

TEST(StableBlockListTest, IteratorStabilityOnErase) {
  StableBlockList<int, 4> list;
  for (int i = 0; i < 8; ++i) {
    list.push_back(i * 10);  // 0, 10, 20, 30, 40, 50, 60, 70
  }

  std::vector<StableBlockList<int, 4>::iterator> iters;
  for (auto it = list.begin(); it != list.end(); ++it) {
    iters.push_back(it);
  }

  // Erase 30 (index 3, which is the last element of first block)
  auto erase_pos = iters[3];
  auto next_it = list.erase(erase_pos);
  EXPECT_EQ(*next_it, 40);
  EXPECT_EQ(list.size(), 7);

  // Verify other iterators are still valid
  EXPECT_EQ(*iters[0], 0);
  EXPECT_EQ(*iters[1], 10);
  EXPECT_EQ(*iters[2], 20);
  // iters[3] is invalid (erased), we shouldn't dereference it.
  EXPECT_EQ(*iters[4], 40);
  EXPECT_EQ(*iters[5], 50);
  EXPECT_EQ(*iters[6], 60);
  EXPECT_EQ(*iters[7], 70);

  std::vector<int> elements;
  for (int x : list) {
    elements.push_back(x);
  }
  EXPECT_THAT(elements, ::testing::ElementsAre(0, 10, 20, 40, 50, 60, 70));
}

TEST(StableBlockListTest, MoveOnlyType) {
  StableBlockList<std::unique_ptr<int>> list;
  list.push_back(std::make_unique<int>(1));
  list.push_back(std::make_unique<int>(2));

  EXPECT_EQ(list.size(), 2);
  EXPECT_EQ(*list.front(), 1);
  EXPECT_EQ(*list.back(), 2);

  list.push_back(std::make_unique<int>(3));  // [1, 2, 3]

  EXPECT_EQ(list.size(), 3);
  auto it = list.begin();
  EXPECT_EQ(**it, 1);
  ++it;
  EXPECT_EQ(**it, 2);
  ++it;
  EXPECT_EQ(**it, 3);

  it = list.begin();
  ++it;            // points to 2
  list.erase(it);  // [1, 3]
  EXPECT_EQ(list.size(), 2);
  EXPECT_EQ(*list.front(), 1);
  EXPECT_EQ(*list.back(), 3);
}

TEST(StableBlockListTest, MultiBlockPushBackAndBackwardTraversal) {
  StableBlockList<int, 8> list;
  const int num_elements = 100;
  for (int i = 0; i < num_elements; ++i) {
    list.push_back(i);
  }
  EXPECT_EQ(list.size(), num_elements);
  EXPECT_EQ(list.front(), 0);
  EXPECT_EQ(list.back(), num_elements - 1);

  // Forward traversal across multiple blocks
  int expected = 0;
  for (int val : list) {
    EXPECT_EQ(val, expected++);
  }
  EXPECT_EQ(expected, num_elements);

  // Backward traversal across multiple blocks
  auto it = list.end();
  for (int i = num_elements - 1; i >= 0; --i) {
    --it;
    EXPECT_EQ(*it, i);
  }
  EXPECT_TRUE(it == list.begin());
}

TEST(StableBlockListTest, SingleBlockReverseIteration) {
  StableBlockList<int, 4> list;
  list.push_back(1);
  list.push_back(2);

  auto it = list.rbegin();
  EXPECT_EQ(*it, 2);
  ++it;
  EXPECT_EQ(*it, 1);
  ++it;
  EXPECT_TRUE(it == list.rend());
}

TEST(StableBlockListTest, SingleElementReverseIteration) {
  StableBlockList<int, 4> list;
  list.push_back(1);

  auto it = list.rbegin();
  EXPECT_EQ(*it, 1);
  ++it;
  EXPECT_TRUE(it == list.rend());
}

TEST(StableBlockListTest, EmptyReverseIteration) {
  StableBlockList<int, 4> list;

  auto it = list.rbegin();
  EXPECT_TRUE(it == list.rend());
}

TEST(StableBlockListTest, EraseLastElementOfMultiBlockList) {
  StableBlockList<int, 4> list;
  // Push 5 elements. Block capacity is 4.
  // Block 0 will have 4 elements (0..3).
  // Block 1 will have 1 element (4).
  for (int i = 0; i < 5; ++i) {
    list.push_back(i);
  }
  // Now erase the last element (4).
  auto it = std::prev(list.end());
  EXPECT_EQ(*it, 4);
  list.erase(it);

  // Check size
  EXPECT_EQ(list.size(), 4);
  // Check back
  EXPECT_EQ(list.back(), 3);

  // Verify we can still traverse
  int expected = 0;
  for (int val : list) {
    EXPECT_EQ(val, expected++);
  }
  EXPECT_EQ(expected, 4);
}

TEST(StableBlockListTest, BlockDeallocationAndReallocation) {
  StableBlockList<int, 2> list;
  list.push_back(1);
  list.push_back(2);
  list.push_back(3);  // Allocates 2nd block

  EXPECT_EQ(list.size(), 3);

  auto it = list.begin();  // points to 1
  list.erase(it);          // 1 is erased
  it = list.begin();       // points to 2
  list.erase(it);  // 2 is erased, 1st block becomes empty and is deallocated!

  EXPECT_EQ(list.size(), 1);
  EXPECT_EQ(list.front(), 3);

  // Now push back another element, it should go to the 2nd block if it has
  // space, or allocate a new block. Since 2nd block has '3' at index 0, it has
  // space at index 1.
  list.push_back(4);
  EXPECT_EQ(list.size(), 2);
  EXPECT_EQ(list.back(), 4);

  // Now 2nd block is full (3, 4). Push another to allocate a new block.
  list.push_back(5);
  EXPECT_EQ(list.size(), 3);
  EXPECT_EQ(list.back(), 5);

  std::vector<int> elements;
  for (int x : list) {
    elements.push_back(x);
  }
  EXPECT_THAT(elements, ::testing::ElementsAre(3, 4, 5));
}

TEST(StableBlockListTest, IteratorBoundaryCases) {
  StableBlockList<int> empty_list;

  // 1. Decrementing end() on empty list should return end() (covers line 505)
  auto empty_it = empty_list.end();
  --empty_it;
  EXPECT_TRUE(empty_it == empty_list.end());

  // 2. Decrementing a default-constructed iterator should return itself (covers
  // line 505)
  StableBlockList<int>::iterator default_it;
  --default_it;
  EXPECT_TRUE(default_it == StableBlockList<int>::iterator());

  // 3. Decrementing begin() on non-empty list should return end() (covers line
  // 530)
  StableBlockList<int> list;
  list.push_back(10);
  auto it = list.begin();
  --it;
  EXPECT_TRUE(it == list.end());
}

TEST(StableBlockListTest, ShrinkToFitReleasesMemory) {
  auto stats = std::make_shared<AllocStats>();
  {
    StableBlockList<int, 2, TrackingAllocator<int>> list(
        (TrackingAllocator<int>(stats)));

    // Push 2 elements. Capacity is 2, so this allocates 1 block.
    list.push_back(1);
    list.push_back(2);
    EXPECT_EQ(stats->allocs, 1);
    EXPECT_EQ(stats->deallocs, 0);

    // Push 3rd element. Allocates 2nd block.
    list.push_back(3);
    EXPECT_EQ(stats->allocs, 2);
    EXPECT_EQ(stats->deallocs, 0);

    // Erase 1st and 2nd elements. 1st block becomes empty and is unlinked.
    // It should be moved to the free list, NOT deallocated.
    auto it = list.begin();
    list.erase(it);
    it = list.begin();
    list.erase(it);

    EXPECT_EQ(stats->allocs, 2);
    EXPECT_EQ(stats->deallocs, 0);

    // Call shrink_to_fit(). This should deallocate the block in the free list.
    list.shrink_to_fit();
    EXPECT_EQ(stats->allocs, 2);
    EXPECT_EQ(stats->deallocs, 1);

    // Push 4th element. Goes to 2nd block (which contains 3 and has space).
    // No new allocation.
    list.push_back(4);
    EXPECT_EQ(stats->allocs, 2);
    EXPECT_EQ(stats->deallocs, 1);

    // Push 5th element. 2nd block is full [3, 4], allocates 3rd block.
    list.push_back(5);
    EXPECT_EQ(stats->allocs, 3);
    EXPECT_EQ(stats->deallocs, 1);
  }
  // Destructor deallocates the remaining active blocks (Block 2 and Block 3).
  EXPECT_EQ(stats->allocs, 3);
  EXPECT_EQ(stats->deallocs, 3);
}

}  // namespace
}  // namespace quiche
