// Copyright 2012 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/observer_list.h"

#include <memory>

#include "base/memory/raw_ptr.h"
#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_.ExtractAsDangling(); }

 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 disrupter2(&observer_list, true);  // Must outlive `disrupter1`.
  Disrupter disrupter1(&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 disrupter2(&observer_list, true);  // Must outlive `disrupter1`.
  Disrupter disrupter1(&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
