// Copyright (c) 2012 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 "base/observer_list.h"

#include "base/memory/raw_ptr.h"

// observer_list.h is a widely included header and its size has significant
// impact on build time. Try not to raise this limit unless necessary. See
// https://chromium.googlesource.com/chromium/src/+/HEAD/docs/wmax_tokens.md
#ifndef NACL_TC_REV
#pragma clang max_tokens_here 480000
#endif

#include <memory>

#include "base/strings/string_piece.h"
#include "base/test/gtest_util.h"
#include "base/threading/simple_thread.h"
#include "build/build_config.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace base {
namespace {

class CheckedBase : public CheckedObserver {
 public:
  virtual void Observe(int x) = 0;
  ~CheckedBase() override = default;
  virtual int GetValue() const { return 0; }
};

class UncheckedBase {
 public:
  virtual void Observe(int x) = 0;
  virtual ~UncheckedBase() = default;
  virtual int GetValue() const { return 0; }
};

// Helper for TYPED_TEST_SUITE machinery to pick the ObserverList under test.
// Keyed off the observer type since ObserverList has too many template args and
// it gets ugly.
template <class Foo>
struct PickObserverList {};
template <>
struct PickObserverList<CheckedBase> {
  template <class TypeParam,
            bool check_empty = false,
            bool allow_reentrancy = true>
  using ObserverListType =
      ObserverList<TypeParam, check_empty, allow_reentrancy>;
};
template <>
struct PickObserverList<UncheckedBase> {
  template <class TypeParam,
            bool check_empty = false,
            bool allow_reentrancy = true>
  using ObserverListType = typename ObserverList<TypeParam,
                                                 check_empty,
                                                 allow_reentrancy>::Unchecked;
};

template <class Foo>
class AdderT : public Foo {
 public:
  explicit AdderT(int scaler) : total(0), scaler_(scaler) {}
  ~AdderT() override = default;

  void Observe(int x) override { total += x * scaler_; }
  int GetValue() const override { return total; }

  int total;

 private:
  int scaler_;
};

template <class ObserverListType,
          class Foo = typename ObserverListType::value_type>
class DisrupterT : public Foo {
 public:
  DisrupterT(ObserverListType* list, Foo* doomed, bool remove_self)
      : list_(list), doomed_(doomed), remove_self_(remove_self) {}
  DisrupterT(ObserverListType* list, Foo* doomed)
      : DisrupterT(list, doomed, false) {}
  DisrupterT(ObserverListType* list, bool remove_self)
      : DisrupterT(list, nullptr, remove_self) {}

  ~DisrupterT() override = default;

  void Observe(int x) override {
    if (remove_self_)
      list_->RemoveObserver(this);
    if (doomed_)
      list_->RemoveObserver(doomed_.get());
  }

  void SetDoomed(Foo* doomed) { doomed_ = doomed; }

 private:
  raw_ptr<ObserverListType> list_;
  raw_ptr<Foo> doomed_;
  bool remove_self_;
};

template <class ObserverListType,
          class Foo = typename ObserverListType::value_type>
class AddInObserve : public Foo {
 public:
  explicit AddInObserve(ObserverListType* observer_list)
      : observer_list(observer_list), to_add_() {}

  void SetToAdd(Foo* to_add) { to_add_ = to_add; }

  void Observe(int x) override {
    if (to_add_) {
      observer_list->AddObserver(to_add_.get());
      to_add_ = nullptr;
    }
  }

  raw_ptr<ObserverListType> observer_list;
  raw_ptr<Foo> to_add_;
};

template <class ObserverListType>
class ObserverListCreator : public DelegateSimpleThread::Delegate {
 public:
  std::unique_ptr<ObserverListType> Create(
      absl::optional<base::ObserverListPolicy> policy = absl::nullopt) {
    policy_ = policy;
    DelegateSimpleThread thread(this, "ListCreator");
    thread.Start();
    thread.Join();
    return std::move(observer_list_);
  }

 private:
  void Run() override {
    if (policy_) {
      observer_list_ = std::make_unique<ObserverListType>(*policy_);
    } else {
      observer_list_ = std::make_unique<ObserverListType>();
    }
  }

  std::unique_ptr<ObserverListType> observer_list_;
  absl::optional<base::ObserverListPolicy> policy_;
};

}  // namespace

class ObserverListTestBase {
 public:
  ObserverListTestBase() = default;
  ObserverListTestBase(const ObserverListTestBase&) = delete;
  ObserverListTestBase& operator=(const ObserverListTestBase&) = delete;

  template <class T>
  const decltype(T::list_.get()) list(const T& iter) {
    return iter.list_.get();
  }

  template <class T>
  typename T::value_type* GetCurrent(T* iter) {
    return iter->GetCurrent();
  }

  // Override GetCurrent() for CheckedObserver. When StdIteratorRemoveFront
  // tries to simulate a sequence to see if it "would" crash, CheckedObservers
  // do, actually, crash with a DCHECK(). Note this check is different to the
  // check during an observer _iteration_. Hence, DCHECK(), not CHECK().
  CheckedBase* GetCurrent(ObserverList<CheckedBase>::iterator* iter) {
    EXPECT_DCHECK_DEATH(return iter->GetCurrent());
    return nullptr;
  }
};

// Templatized test fixture that can pick between CheckedBase and UncheckedBase.
template <class ObserverType>
class ObserverListTest : public ObserverListTestBase, public ::testing::Test {
 public:
  template <class T>
  using ObserverList =
      typename PickObserverList<ObserverType>::template ObserverListType<T>;

  using iterator = typename ObserverList<ObserverType>::iterator;
  using const_iterator = typename ObserverList<ObserverType>::const_iterator;

  ObserverListTest() = default;
  ObserverListTest(const ObserverListTest&) = delete;
  ObserverListTest& operator=(const ObserverListTest&) = delete;
};

using ObserverTypes = ::testing::Types<CheckedBase, UncheckedBase>;
TYPED_TEST_SUITE(ObserverListTest, ObserverTypes);

// TYPED_TEST causes the test parent class to be a template parameter, which
// makes the syntax for referring to the types awkward. Create aliases in local
// scope with clearer names. Unfortunately, we also need some trailing cruft to
// avoid "unused local type alias" warnings.
#define DECLARE_TYPES                                                       \
  using Foo = TypeParam;                                                    \
  using ObserverListFoo =                                                   \
      typename PickObserverList<TypeParam>::template ObserverListType<Foo>; \
  using Adder = AdderT<Foo>;                                                \
  using Disrupter = DisrupterT<ObserverListFoo>;                            \
  using const_iterator = typename TestFixture::const_iterator;              \
  using iterator = typename TestFixture::iterator;                          \
  (void)reinterpret_cast<Disrupter*>(0);                                    \
  (void)reinterpret_cast<Adder*>(0);                                        \
  (void)reinterpret_cast<const_iterator*>(0);                               \
  (void)reinterpret_cast<iterator*>(0)

TYPED_TEST(ObserverListTest, BasicTest) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  const ObserverListFoo& const_observer_list = observer_list;

  {
    const const_iterator it1 = const_observer_list.begin();
    EXPECT_EQ(it1, const_observer_list.end());
    // Iterator copy.
    const const_iterator it2 = it1;
    EXPECT_EQ(it2, it1);
    // Iterator assignment.
    const_iterator it3;
    it3 = it2;
    EXPECT_EQ(it3, it1);
    EXPECT_EQ(it3, it2);
    // Self assignment.
    it3 = *&it3;  // The *& defeats Clang's -Wself-assign warning.
    EXPECT_EQ(it3, it1);
    EXPECT_EQ(it3, it2);
  }

  {
    const iterator it1 = observer_list.begin();
    EXPECT_EQ(it1, observer_list.end());
    // Iterator copy.
    const iterator it2 = it1;
    EXPECT_EQ(it2, it1);
    // Iterator assignment.
    iterator it3;
    it3 = it2;
    EXPECT_EQ(it3, it1);
    EXPECT_EQ(it3, it2);
    // Self assignment.
    it3 = *&it3;  // The *& defeats Clang's -Wself-assign warning.
    EXPECT_EQ(it3, it1);
    EXPECT_EQ(it3, it2);
  }

  Adder a(1), b(-1), c(1), d(-1), e(-1);
  Disrupter evil(&observer_list, &c);

  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);

  EXPECT_TRUE(const_observer_list.HasObserver(&a));
  EXPECT_FALSE(const_observer_list.HasObserver(&c));

  {
    const const_iterator it1 = const_observer_list.begin();
    EXPECT_NE(it1, const_observer_list.end());
    // Iterator copy.
    const const_iterator it2 = it1;
    EXPECT_EQ(it2, it1);
    EXPECT_NE(it2, const_observer_list.end());
    // Iterator assignment.
    const_iterator it3;
    it3 = it2;
    EXPECT_EQ(it3, it1);
    EXPECT_EQ(it3, it2);
    // Self assignment.
    it3 = *&it3;  // The *& defeats Clang's -Wself-assign warning.
    EXPECT_EQ(it3, it1);
    EXPECT_EQ(it3, it2);
    // Iterator post increment.
    const_iterator it4 = it3++;
    EXPECT_EQ(it4, it1);
    EXPECT_EQ(it4, it2);
    EXPECT_NE(it4, it3);
  }

  {
    const iterator it1 = observer_list.begin();
    EXPECT_NE(it1, observer_list.end());
    // Iterator copy.
    const iterator it2 = it1;
    EXPECT_EQ(it2, it1);
    EXPECT_NE(it2, observer_list.end());
    // Iterator assignment.
    iterator it3;
    it3 = it2;
    EXPECT_EQ(it3, it1);
    EXPECT_EQ(it3, it2);
    // Self assignment.
    it3 = *&it3;  // The *& defeats Clang's -Wself-assign warning.
    EXPECT_EQ(it3, it1);
    EXPECT_EQ(it3, it2);
    // Iterator post increment.
    iterator it4 = it3++;
    EXPECT_EQ(it4, it1);
    EXPECT_EQ(it4, it2);
    EXPECT_NE(it4, it3);
  }

  for (auto& observer : observer_list)
    observer.Observe(10);

  observer_list.AddObserver(&evil);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&d);

  // Removing an observer not in the list should do nothing.
  observer_list.RemoveObserver(&e);

  for (auto& observer : observer_list)
    observer.Observe(10);

  EXPECT_EQ(20, a.total);
  EXPECT_EQ(-20, b.total);
  EXPECT_EQ(0, c.total);
  EXPECT_EQ(-10, d.total);
  EXPECT_EQ(0, e.total);
}

TYPED_TEST(ObserverListTest, CreatedAndUsedOnDifferentThreads) {
  DECLARE_TYPES;

  ObserverListCreator<ObserverListFoo> list_creator;
  Adder a(1);
  // Check with default constructor
  {
    std::unique_ptr<ObserverListFoo> observer_list = list_creator.Create();
    observer_list->AddObserver(&a);
    for (auto& observer : *observer_list) {
      observer.Observe(1);
    }
    EXPECT_EQ(1, a.GetValue());
  }

  // Check with constructor taking explicit policy
  {
    std::unique_ptr<ObserverListFoo> observer_list =
        list_creator.Create(base::ObserverListPolicy::EXISTING_ONLY);
    observer_list->AddObserver(&a);
    for (auto& observer : *observer_list) {
      observer.Observe(1);
    }
    EXPECT_EQ(2, a.GetValue());
  }
}

TYPED_TEST(ObserverListTest, CompactsWhenNoActiveIterator) {
  DECLARE_TYPES;
  using ObserverListConstFoo =
      typename TestFixture::template ObserverList<const Foo>;

  ObserverListConstFoo ol;
  const ObserverListConstFoo& col = ol;

  const Adder a(1);
  const Adder b(2);
  const Adder c(3);

  ol.AddObserver(&a);
  ol.AddObserver(&b);

  EXPECT_TRUE(col.HasObserver(&a));
  EXPECT_FALSE(col.HasObserver(&c));

  EXPECT_TRUE(!col.empty());

  using It = typename ObserverListConstFoo::const_iterator;

  {
    It it = col.begin();
    EXPECT_NE(it, col.end());
    It ita = it;
    EXPECT_EQ(ita, it);
    EXPECT_NE(++it, col.end());
    EXPECT_NE(ita, it);
    It itb = it;
    EXPECT_EQ(itb, it);
    EXPECT_EQ(++it, col.end());

    EXPECT_TRUE(!col.empty());
    EXPECT_EQ(&*ita, &a);
    EXPECT_EQ(&*itb, &b);

    ol.RemoveObserver(&a);
    EXPECT_TRUE(!col.empty());
    EXPECT_FALSE(col.HasObserver(&a));
    EXPECT_EQ(&*itb, &b);

    ol.RemoveObserver(&b);
    EXPECT_FALSE(!col.empty());
    EXPECT_FALSE(col.HasObserver(&a));
    EXPECT_FALSE(col.HasObserver(&b));

    it = It();
    ita = It();
    EXPECT_FALSE(!col.empty());
    ita = itb;
    itb = It();
    EXPECT_FALSE(!col.empty());
    ita = It();
    EXPECT_FALSE(!col.empty());
  }

  ol.AddObserver(&a);
  ol.AddObserver(&b);
  EXPECT_TRUE(!col.empty());
  ol.Clear();
  EXPECT_FALSE(!col.empty());

  ol.AddObserver(&a);
  ol.AddObserver(&b);
  EXPECT_TRUE(!col.empty());
  {
    const It it = col.begin();
    ol.Clear();
    EXPECT_FALSE(!col.empty());
  }
  EXPECT_FALSE(!col.empty());
}

TYPED_TEST(ObserverListTest, DisruptSelf) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  Adder a(1), b(-1), c(1), d(-1);
  Disrupter evil(&observer_list, true);

  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);

  for (auto& observer : observer_list)
    observer.Observe(10);

  observer_list.AddObserver(&evil);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&d);

  for (auto& observer : observer_list)
    observer.Observe(10);

  EXPECT_EQ(20, a.total);
  EXPECT_EQ(-20, b.total);
  EXPECT_EQ(10, c.total);
  EXPECT_EQ(-10, d.total);
}

TYPED_TEST(ObserverListTest, DisruptBefore) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  Adder a(1), b(-1), c(1), d(-1);
  Disrupter evil(&observer_list, &b);

  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);
  observer_list.AddObserver(&evil);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&d);

  for (auto& observer : observer_list)
    observer.Observe(10);
  for (auto& observer : observer_list)
    observer.Observe(10);

  EXPECT_EQ(20, a.total);
  EXPECT_EQ(-10, b.total);
  EXPECT_EQ(20, c.total);
  EXPECT_EQ(-20, d.total);
}

TYPED_TEST(ObserverListTest, Existing) {
  DECLARE_TYPES;
  ObserverListFoo observer_list(ObserverListPolicy::EXISTING_ONLY);
  Adder a(1);
  AddInObserve<ObserverListFoo> b(&observer_list);
  Adder c(1);
  b.SetToAdd(&c);

  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);

  for (auto& observer : observer_list)
    observer.Observe(1);

  EXPECT_FALSE(b.to_add_);
  // B's adder should not have been notified because it was added during
  // notification.
  EXPECT_EQ(0, c.total);

  // Notify again to make sure b's adder is notified.
  for (auto& observer : observer_list)
    observer.Observe(1);
  EXPECT_EQ(1, c.total);
}

template <class ObserverListType,
          class Foo = typename ObserverListType::value_type>
class AddInClearObserve : public Foo {
 public:
  explicit AddInClearObserve(ObserverListType* list)
      : list_(list), added_(false), adder_(1) {}

  void Observe(int /* x */) override {
    list_->Clear();
    list_->AddObserver(&adder_);
    added_ = true;
  }

  bool added() const { return added_; }
  const AdderT<Foo>& adder() const { return adder_; }

 private:
  const raw_ptr<ObserverListType> list_;

  bool added_;
  AdderT<Foo> adder_;
};

TYPED_TEST(ObserverListTest, ClearNotifyAll) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  AddInClearObserve<ObserverListFoo> a(&observer_list);

  observer_list.AddObserver(&a);

  for (auto& observer : observer_list)
    observer.Observe(1);
  EXPECT_TRUE(a.added());
  EXPECT_EQ(1, a.adder().total)
      << "Adder should observe once and have sum of 1.";
}

TYPED_TEST(ObserverListTest, ClearNotifyExistingOnly) {
  DECLARE_TYPES;
  ObserverListFoo observer_list(ObserverListPolicy::EXISTING_ONLY);
  AddInClearObserve<ObserverListFoo> a(&observer_list);

  observer_list.AddObserver(&a);

  for (auto& observer : observer_list)
    observer.Observe(1);
  EXPECT_TRUE(a.added());
  EXPECT_EQ(0, a.adder().total)
      << "Adder should not observe, so sum should still be 0.";
}

template <class ObserverListType,
          class Foo = typename ObserverListType::value_type>
class ListDestructor : public Foo {
 public:
  explicit ListDestructor(ObserverListType* list) : list_(list) {}
  ~ListDestructor() override = default;

  void Observe(int x) override { delete list_; }

 private:
  raw_ptr<ObserverListType> list_;
};

TYPED_TEST(ObserverListTest, IteratorOutlivesList) {
  DECLARE_TYPES;
  ObserverListFoo* observer_list = new ObserverListFoo;
  ListDestructor<ObserverListFoo> a(observer_list);
  observer_list->AddObserver(&a);

  for (auto& observer : *observer_list)
    observer.Observe(0);

  // There are no EXPECT* statements for this test, if we catch
  // use-after-free errors for observer_list (eg with ASan) then
  // this test has failed.  See http://crbug.com/85296.
}

TYPED_TEST(ObserverListTest, BasicStdIterator) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;

  // An optimization: begin() and end() do not involve weak pointers on
  // empty list.
  EXPECT_FALSE(this->list(observer_list.begin()));
  EXPECT_FALSE(this->list(observer_list.end()));

  // Iterate over empty list: no effect, no crash.
  for (auto& i : observer_list)
    i.Observe(10);

  Adder a(1), b(-1), c(1), d(-1);

  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&d);

  for (iterator i = observer_list.begin(), e = observer_list.end(); i != e; ++i)
    i->Observe(1);

  EXPECT_EQ(1, a.total);
  EXPECT_EQ(-1, b.total);
  EXPECT_EQ(1, c.total);
  EXPECT_EQ(-1, d.total);

  // Check an iteration over a 'const view' for a given container.
  const ObserverListFoo& const_list = observer_list;
  for (const_iterator i = const_list.begin(), e = const_list.end(); i != e;
       ++i) {
    EXPECT_EQ(1, std::abs(i->GetValue()));
  }

  for (const auto& o : const_list)
    EXPECT_EQ(1, std::abs(o.GetValue()));
}

TYPED_TEST(ObserverListTest, StdIteratorRemoveItself) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  Adder a(1), b(-1), c(1), d(-1);
  Disrupter disrupter(&observer_list, true);

  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);
  observer_list.AddObserver(&disrupter);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&d);

  for (auto& o : observer_list)
    o.Observe(1);

  for (auto& o : observer_list)
    o.Observe(10);

  EXPECT_EQ(11, a.total);
  EXPECT_EQ(-11, b.total);
  EXPECT_EQ(11, c.total);
  EXPECT_EQ(-11, d.total);
}

TYPED_TEST(ObserverListTest, StdIteratorRemoveBefore) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  Adder a(1), b(-1), c(1), d(-1);
  Disrupter disrupter(&observer_list, &b);

  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);
  observer_list.AddObserver(&disrupter);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&d);

  for (auto& o : observer_list)
    o.Observe(1);

  for (auto& o : observer_list)
    o.Observe(10);

  EXPECT_EQ(11, a.total);
  EXPECT_EQ(-1, b.total);
  EXPECT_EQ(11, c.total);
  EXPECT_EQ(-11, d.total);
}

TYPED_TEST(ObserverListTest, StdIteratorRemoveAfter) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  Adder a(1), b(-1), c(1), d(-1);
  Disrupter disrupter(&observer_list, &c);

  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);
  observer_list.AddObserver(&disrupter);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&d);

  for (auto& o : observer_list)
    o.Observe(1);

  for (auto& o : observer_list)
    o.Observe(10);

  EXPECT_EQ(11, a.total);
  EXPECT_EQ(-11, b.total);
  EXPECT_EQ(0, c.total);
  EXPECT_EQ(-11, d.total);
}

TYPED_TEST(ObserverListTest, StdIteratorRemoveAfterFront) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  Adder a(1), b(-1), c(1), d(-1);
  Disrupter disrupter(&observer_list, &a);

  observer_list.AddObserver(&a);
  observer_list.AddObserver(&disrupter);
  observer_list.AddObserver(&b);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&d);

  for (auto& o : observer_list)
    o.Observe(1);

  for (auto& o : observer_list)
    o.Observe(10);

  EXPECT_EQ(1, a.total);
  EXPECT_EQ(-11, b.total);
  EXPECT_EQ(11, c.total);
  EXPECT_EQ(-11, d.total);
}

TYPED_TEST(ObserverListTest, StdIteratorRemoveBeforeBack) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  Adder a(1), b(-1), c(1), d(-1);
  Disrupter disrupter(&observer_list, &d);

  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&disrupter);
  observer_list.AddObserver(&d);

  for (auto& o : observer_list)
    o.Observe(1);

  for (auto& o : observer_list)
    o.Observe(10);

  EXPECT_EQ(11, a.total);
  EXPECT_EQ(-11, b.total);
  EXPECT_EQ(11, c.total);
  EXPECT_EQ(0, d.total);
}

TYPED_TEST(ObserverListTest, StdIteratorRemoveFront) {
  DECLARE_TYPES;
  using iterator = typename TestFixture::iterator;
  ObserverListFoo observer_list;
  Adder a(1), b(-1), c(1), d(-1);
  Disrupter disrupter(&observer_list, true);

  observer_list.AddObserver(&disrupter);
  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&d);

  bool test_disruptor = true;
  for (iterator i = observer_list.begin(), e = observer_list.end(); i != e;
       ++i) {
    i->Observe(1);
    // Check that second call to i->Observe() would crash here.
    if (test_disruptor) {
      EXPECT_FALSE(this->GetCurrent(&i));
      test_disruptor = false;
    }
  }

  for (auto& o : observer_list)
    o.Observe(10);

  EXPECT_EQ(11, a.total);
  EXPECT_EQ(-11, b.total);
  EXPECT_EQ(11, c.total);
  EXPECT_EQ(-11, d.total);
}

TYPED_TEST(ObserverListTest, StdIteratorRemoveBack) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  Adder a(1), b(-1), c(1), d(-1);
  Disrupter disrupter(&observer_list, true);

  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&d);
  observer_list.AddObserver(&disrupter);

  for (auto& o : observer_list)
    o.Observe(1);

  for (auto& o : observer_list)
    o.Observe(10);

  EXPECT_EQ(11, a.total);
  EXPECT_EQ(-11, b.total);
  EXPECT_EQ(11, c.total);
  EXPECT_EQ(-11, d.total);
}

TYPED_TEST(ObserverListTest, NestedLoop) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  Adder a(1), b(-1), c(1), d(-1);
  Disrupter disrupter(&observer_list, true);

  observer_list.AddObserver(&disrupter);
  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);
  observer_list.AddObserver(&c);
  observer_list.AddObserver(&d);

  for (auto& observer : observer_list) {
    observer.Observe(10);

    for (auto& nested_observer : observer_list)
      nested_observer.Observe(1);
  }

  EXPECT_EQ(15, a.total);
  EXPECT_EQ(-15, b.total);
  EXPECT_EQ(15, c.total);
  EXPECT_EQ(-15, d.total);
}

TYPED_TEST(ObserverListTest, NonCompactList) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  Adder a(1), b(-1);

  Disrupter disrupter1(&observer_list, true);
  Disrupter disrupter2(&observer_list, true);

  // Disrupt itself and another one.
  disrupter1.SetDoomed(&disrupter2);

  observer_list.AddObserver(&disrupter1);
  observer_list.AddObserver(&disrupter2);
  observer_list.AddObserver(&a);
  observer_list.AddObserver(&b);

  for (auto& observer : observer_list) {
    // Get the { nullptr, nullptr, &a, &b } non-compact list
    // on the first inner pass.
    observer.Observe(10);

    for (auto& nested_observer : observer_list)
      nested_observer.Observe(1);
  }

  EXPECT_EQ(13, a.total);
  EXPECT_EQ(-13, b.total);
}

TYPED_TEST(ObserverListTest, BecomesEmptyThanNonEmpty) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;
  Adder a(1), b(-1);

  Disrupter disrupter1(&observer_list, true);
  Disrupter disrupter2(&observer_list, true);

  // Disrupt itself and another one.
  disrupter1.SetDoomed(&disrupter2);

  observer_list.AddObserver(&disrupter1);
  observer_list.AddObserver(&disrupter2);

  bool add_observers = true;
  for (auto& observer : observer_list) {
    // Get the { nullptr, nullptr } empty list on the first inner pass.
    observer.Observe(10);

    for (auto& nested_observer : observer_list)
      nested_observer.Observe(1);

    if (add_observers) {
      observer_list.AddObserver(&a);
      observer_list.AddObserver(&b);
      add_observers = false;
    }
  }

  EXPECT_EQ(12, a.total);
  EXPECT_EQ(-12, b.total);
}

TYPED_TEST(ObserverListTest, AddObserverInTheLastObserve) {
  DECLARE_TYPES;
  ObserverListFoo observer_list;

  AddInObserve<ObserverListFoo> a(&observer_list);
  Adder b(-1);

  a.SetToAdd(&b);
  observer_list.AddObserver(&a);

  auto it = observer_list.begin();
  while (it != observer_list.end()) {
    auto& observer = *it;
    // Intentionally increment the iterator before calling Observe(). The
    // ObserverList starts with only one observer, and it == observer_list.end()
    // should be true after the next line.
    ++it;
    // However, the first Observe() call will add a second observer: at this
    // point, it != observer_list.end() should be true, and Observe() should be
    // called on the newly added observer on the next iteration of the loop.
    observer.Observe(10);
  }

  EXPECT_EQ(-10, b.total);
}

class MockLogAssertHandler {
 public:
  MOCK_METHOD4(
      HandleLogAssert,
      void(const char*, int, const base::StringPiece, const base::StringPiece));
};

#if DCHECK_IS_ON()
TYPED_TEST(ObserverListTest, NonReentrantObserverList) {
  DECLARE_TYPES;
  using NonReentrantObserverListFoo = typename PickObserverList<
      Foo>::template ObserverListType<Foo, /*check_empty=*/false,
                                      /*allow_reentrancy=*/false>;
  NonReentrantObserverListFoo non_reentrant_observer_list;
  Adder a(1);
  non_reentrant_observer_list.AddObserver(&a);

  EXPECT_DCHECK_DEATH({
    for (const Foo& observer : non_reentrant_observer_list) {
      for (const Foo& nested_observer : non_reentrant_observer_list) {
        std::ignore = observer;
        std::ignore = nested_observer;
      }
    }
  });
}

TYPED_TEST(ObserverListTest, ReentrantObserverList) {
  DECLARE_TYPES;
  using ReentrantObserverListFoo = typename PickObserverList<
      Foo>::template ObserverListType<Foo, /*check_empty=*/false,
                                      /*allow_reentrancy=*/true>;
  ReentrantObserverListFoo reentrant_observer_list;
  Adder a(1);
  reentrant_observer_list.AddObserver(&a);
  bool passed = false;
  for (const Foo& observer : reentrant_observer_list) {
    for (const Foo& nested_observer : reentrant_observer_list) {
      std::ignore = observer;
      std::ignore = nested_observer;
      passed = true;
    }
  }
  EXPECT_TRUE(passed);
}
#endif

class TestCheckedObserver : public CheckedObserver {
 public:
  explicit TestCheckedObserver(int* count) : count_(count) {}
  TestCheckedObserver(const TestCheckedObserver&) = delete;
  TestCheckedObserver& operator=(const TestCheckedObserver&) = delete;

  void Observe() { ++(*count_); }

 private:
  raw_ptr<int> count_;
};

// A second, identical observer, used to test multiple inheritance.
class TestCheckedObserver2 : public CheckedObserver {
 public:
  explicit TestCheckedObserver2(int* count) : count_(count) {}
  TestCheckedObserver2(const TestCheckedObserver2&) = delete;
  TestCheckedObserver2& operator=(const TestCheckedObserver2&) = delete;

  void Observe() { ++(*count_); }

 private:
  raw_ptr<int> count_;
};

using CheckedObserverListTest = ::testing::Test;

// Test Observers that CHECK() when a UAF might otherwise occur.
TEST_F(CheckedObserverListTest, CheckedObserver) {
  // See comments below about why this is unique_ptr.
  auto list = std::make_unique<ObserverList<TestCheckedObserver>>();
  int count1 = 0;
  int count2 = 0;
  TestCheckedObserver l1(&count1);
  list->AddObserver(&l1);
  {
    TestCheckedObserver l2(&count2);
    list->AddObserver(&l2);
    for (auto& observer : *list)
      observer.Observe();
    EXPECT_EQ(1, count1);
    EXPECT_EQ(1, count2);
  }
  {
    auto it = list->begin();
    it->Observe();
    // For CheckedObservers, a CHECK() occurs when advancing the iterator. (On
    // calling the observer method would be too late since the pointer would
    // already be null by then).
    EXPECT_CHECK_DEATH(it++);

    // On the non-death fork, no UAF occurs since the deleted observer is never
    // notified, but also the observer list still has |l2| in it. Check that.
    list->RemoveObserver(&l1);
    EXPECT_TRUE(!list->empty());

    // Now (in the non-death fork()) there's a problem. To delete |it|, we need
    // to compact the list, but that needs to iterate, which would CHECK again.
    // We can't remove |l2| (it's null). But we can delete |list|, which makes
    // the weak pointer in the iterator itself null.
    list.reset();
  }
  EXPECT_EQ(2, count1);
  EXPECT_EQ(1, count2);
}

class MultiObserver : public TestCheckedObserver,
                      public TestCheckedObserver2,
                      public AdderT<UncheckedBase> {
 public:
  MultiObserver(int* checked_count, int* two_count)
      : TestCheckedObserver(checked_count),
        TestCheckedObserver2(two_count),
        AdderT(1) {}
};

// Test that observers behave as expected when observing multiple interfaces
// with different traits.
TEST_F(CheckedObserverListTest, MultiObserver) {
  // Observe two checked observer lists. This is to ensure the WeakPtrFactory
  // in CheckedObserver can correctly service multiple ObserverLists.
  ObserverList<TestCheckedObserver> checked_list;
  ObserverList<TestCheckedObserver2> two_list;

  ObserverList<UncheckedBase>::Unchecked unsafe_list;

  int counts[2] = {};

  auto multi_observer = std::make_unique<MultiObserver>(&counts[0], &counts[1]);
  two_list.AddObserver(multi_observer.get());
  checked_list.AddObserver(multi_observer.get());
  unsafe_list.AddObserver(multi_observer.get());

  auto iterate_over = [](auto* list) {
    for (auto& observer : *list)
      observer.Observe();
  };
  iterate_over(&two_list);
  iterate_over(&checked_list);
  for (auto& observer : unsafe_list)
    observer.Observe(10);

  EXPECT_EQ(10, multi_observer->GetValue());
  for (const auto& count : counts)
    EXPECT_EQ(1, count);

  unsafe_list.RemoveObserver(multi_observer.get());  // Avoid a use-after-free.

  multi_observer.reset();
  EXPECT_CHECK_DEATH(iterate_over(&checked_list));

  for (const auto& count : counts)
    EXPECT_EQ(1, count);
}

}  // namespace base
