// Copyright 2013 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/callback_list.h"

#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace {

class Listener {
 public:
  Listener() : total_(0), scaler_(1) {}
  explicit Listener(int scaler) : total_(0), scaler_(scaler) {}
  void IncrementTotal() { total_++; }
  void IncrementByMultipleOfScaler(int x) { total_ += x * scaler_; }

  int total() const { return total_; }

 private:
  int total_;
  int scaler_;
  DISALLOW_COPY_AND_ASSIGN(Listener);
};

class Remover {
 public:
  Remover() : total_(0) {}
  void IncrementTotalAndRemove() {
    total_++;
    removal_subscription_.reset();
  }
  void SetSubscriptionToRemove(
      std::unique_ptr<CallbackList<void(void)>::Subscription> sub) {
    removal_subscription_ = std::move(sub);
  }

  int total() const { return total_; }

 private:
  int total_;
  std::unique_ptr<CallbackList<void(void)>::Subscription> removal_subscription_;
  DISALLOW_COPY_AND_ASSIGN(Remover);
};

class Adder {
 public:
  explicit Adder(CallbackList<void(void)>* cb_reg)
      : added_(false),
        total_(0),
        cb_reg_(cb_reg) {
  }
  void AddCallback() {
    if (!added_) {
      added_ = true;
      subscription_ =
          cb_reg_->Add(Bind(&Adder::IncrementTotal, Unretained(this)));
    }
  }
  void IncrementTotal() { total_++; }

  bool added() const { return added_; }

  int total() const { return total_; }

 private:
  bool added_;
  int total_;
  CallbackList<void(void)>* cb_reg_;
  std::unique_ptr<CallbackList<void(void)>::Subscription> subscription_;
  DISALLOW_COPY_AND_ASSIGN(Adder);
};

class Summer {
 public:
  Summer() : value_(0) {}

  void AddOneParam(int a) { value_ = a; }
  void AddTwoParam(int a, int b) { value_ = a + b; }
  void AddThreeParam(int a, int b, int c) { value_ = a + b + c; }
  void AddFourParam(int a, int b, int c, int d) { value_ = a + b + c + d; }
  void AddFiveParam(int a, int b, int c, int d, int e) {
    value_ = a + b + c + d + e;
  }
  void AddSixParam(int a, int b, int c, int d, int e , int f) {
    value_ = a + b + c + d + e + f;
  }

  int value() const { return value_; }

 private:
  int value_;
  DISALLOW_COPY_AND_ASSIGN(Summer);
};

class Counter {
 public:
  Counter() : value_(0) {}

  void Increment() { value_++; }

  int value() const { return value_; }

 private:
  int value_;
  DISALLOW_COPY_AND_ASSIGN(Counter);
};

// Sanity check that we can instantiate a CallbackList for each arity.
TEST(CallbackListTest, ArityTest) {
  Summer s;

  CallbackList<void(int)> c1;
  std::unique_ptr<CallbackList<void(int)>::Subscription> subscription1 =
      c1.Add(Bind(&Summer::AddOneParam, Unretained(&s)));

  c1.Notify(1);
  EXPECT_EQ(1, s.value());

  CallbackList<void(int, int)> c2;
  std::unique_ptr<CallbackList<void(int, int)>::Subscription> subscription2 =
      c2.Add(Bind(&Summer::AddTwoParam, Unretained(&s)));

  c2.Notify(1, 2);
  EXPECT_EQ(3, s.value());

  CallbackList<void(int, int, int)> c3;
  std::unique_ptr<CallbackList<void(int, int, int)>::Subscription>
      subscription3 = c3.Add(Bind(&Summer::AddThreeParam, Unretained(&s)));

  c3.Notify(1, 2, 3);
  EXPECT_EQ(6, s.value());

  CallbackList<void(int, int, int, int)> c4;
  std::unique_ptr<CallbackList<void(int, int, int, int)>::Subscription>
      subscription4 = c4.Add(Bind(&Summer::AddFourParam, Unretained(&s)));

  c4.Notify(1, 2, 3, 4);
  EXPECT_EQ(10, s.value());

  CallbackList<void(int, int, int, int, int)> c5;
  std::unique_ptr<CallbackList<void(int, int, int, int, int)>::Subscription>
      subscription5 = c5.Add(Bind(&Summer::AddFiveParam, Unretained(&s)));

  c5.Notify(1, 2, 3, 4, 5);
  EXPECT_EQ(15, s.value());

  CallbackList<void(int, int, int, int, int, int)> c6;
  std::unique_ptr<
      CallbackList<void(int, int, int, int, int, int)>::Subscription>
      subscription6 = c6.Add(Bind(&Summer::AddSixParam, Unretained(&s)));

  c6.Notify(1, 2, 3, 4, 5, 6);
  EXPECT_EQ(21, s.value());
}

// Sanity check that closures added to the list will be run, and those removed
// from the list will not be run.
TEST(CallbackListTest, BasicTest) {
  CallbackList<void(void)> cb_reg;
  Listener a, b, c;

  std::unique_ptr<CallbackList<void(void)>::Subscription> a_subscription =
      cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&a)));
  std::unique_ptr<CallbackList<void(void)>::Subscription> b_subscription =
      cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&b)));

  EXPECT_TRUE(a_subscription.get());
  EXPECT_TRUE(b_subscription.get());

  cb_reg.Notify();

  EXPECT_EQ(1, a.total());
  EXPECT_EQ(1, b.total());

  b_subscription.reset();

  std::unique_ptr<CallbackList<void(void)>::Subscription> c_subscription =
      cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&c)));

  cb_reg.Notify();

  EXPECT_EQ(2, a.total());
  EXPECT_EQ(1, b.total());
  EXPECT_EQ(1, c.total());

  a_subscription.reset();
  b_subscription.reset();
  c_subscription.reset();
}

// Sanity check that callbacks with details added to the list will be run, with
// the correct details, and those removed from the list will not be run.
TEST(CallbackListTest, BasicTestWithParams) {
  CallbackList<void(int)> cb_reg;
  Listener a(1), b(-1), c(1);

  std::unique_ptr<CallbackList<void(int)>::Subscription> a_subscription =
      cb_reg.Add(Bind(&Listener::IncrementByMultipleOfScaler, Unretained(&a)));
  std::unique_ptr<CallbackList<void(int)>::Subscription> b_subscription =
      cb_reg.Add(Bind(&Listener::IncrementByMultipleOfScaler, Unretained(&b)));

  EXPECT_TRUE(a_subscription.get());
  EXPECT_TRUE(b_subscription.get());

  cb_reg.Notify(10);

  EXPECT_EQ(10, a.total());
  EXPECT_EQ(-10, b.total());

  b_subscription.reset();

  std::unique_ptr<CallbackList<void(int)>::Subscription> c_subscription =
      cb_reg.Add(Bind(&Listener::IncrementByMultipleOfScaler, Unretained(&c)));

  cb_reg.Notify(10);

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

  a_subscription.reset();
  b_subscription.reset();
  c_subscription.reset();
}

// Test the a callback can remove itself or a different callback from the list
// during iteration without invalidating the iterator.
TEST(CallbackListTest, RemoveCallbacksDuringIteration) {
  CallbackList<void(void)> cb_reg;
  Listener a, b;
  Remover remover_1, remover_2;

  std::unique_ptr<CallbackList<void(void)>::Subscription> remover_1_sub =
      cb_reg.Add(
          Bind(&Remover::IncrementTotalAndRemove, Unretained(&remover_1)));
  std::unique_ptr<CallbackList<void(void)>::Subscription> remover_2_sub =
      cb_reg.Add(
          Bind(&Remover::IncrementTotalAndRemove, Unretained(&remover_2)));
  std::unique_ptr<CallbackList<void(void)>::Subscription> a_subscription =
      cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&a)));
  std::unique_ptr<CallbackList<void(void)>::Subscription> b_subscription =
      cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&b)));

  // |remover_1| will remove itself.
  remover_1.SetSubscriptionToRemove(std::move(remover_1_sub));
  // |remover_2| will remove a.
  remover_2.SetSubscriptionToRemove(std::move(a_subscription));

  cb_reg.Notify();

  // |remover_1| runs once (and removes itself), |remover_2| runs once (and
  // removes a), |a| never runs, and |b| runs once.
  EXPECT_EQ(1, remover_1.total());
  EXPECT_EQ(1, remover_2.total());
  EXPECT_EQ(0, a.total());
  EXPECT_EQ(1, b.total());

  cb_reg.Notify();

  // Only |remover_2| and |b| run this time.
  EXPECT_EQ(1, remover_1.total());
  EXPECT_EQ(2, remover_2.total());
  EXPECT_EQ(0, a.total());
  EXPECT_EQ(2, b.total());
}

// Test that a callback can add another callback to the list durning iteration
// without invalidating the iterator. The newly added callback should be run on
// the current iteration as will all other callbacks in the list.
TEST(CallbackListTest, AddCallbacksDuringIteration) {
  CallbackList<void(void)> cb_reg;
  Adder a(&cb_reg);
  Listener b;
  std::unique_ptr<CallbackList<void(void)>::Subscription> a_subscription =
      cb_reg.Add(Bind(&Adder::AddCallback, Unretained(&a)));
  std::unique_ptr<CallbackList<void(void)>::Subscription> b_subscription =
      cb_reg.Add(Bind(&Listener::IncrementTotal, Unretained(&b)));

  cb_reg.Notify();

  EXPECT_EQ(1, a.total());
  EXPECT_EQ(1, b.total());
  EXPECT_TRUE(a.added());

  cb_reg.Notify();

  EXPECT_EQ(2, a.total());
  EXPECT_EQ(2, b.total());
}

// Sanity check: notifying an empty list is a no-op.
TEST(CallbackListTest, EmptyList) {
  CallbackList<void(void)> cb_reg;

  cb_reg.Notify();
}

TEST(CallbackList, RemovalCallback) {
  Counter remove_count;
  CallbackList<void(void)> cb_reg;
  cb_reg.set_removal_callback(
      Bind(&Counter::Increment, Unretained(&remove_count)));

  std::unique_ptr<CallbackList<void(void)>::Subscription> subscription =
      cb_reg.Add(DoNothing());

  // Removing a subscription outside of iteration signals the callback.
  EXPECT_EQ(0, remove_count.value());
  subscription.reset();
  EXPECT_EQ(1, remove_count.value());

  // Configure two subscriptions to remove themselves.
  Remover remover_1, remover_2;
  std::unique_ptr<CallbackList<void(void)>::Subscription> remover_1_sub =
      cb_reg.Add(
          Bind(&Remover::IncrementTotalAndRemove, Unretained(&remover_1)));
  std::unique_ptr<CallbackList<void(void)>::Subscription> remover_2_sub =
      cb_reg.Add(
          Bind(&Remover::IncrementTotalAndRemove, Unretained(&remover_2)));
  remover_1.SetSubscriptionToRemove(std::move(remover_1_sub));
  remover_2.SetSubscriptionToRemove(std::move(remover_2_sub));

  // The callback should be signaled exactly once.
  EXPECT_EQ(1, remove_count.value());
  cb_reg.Notify();
  EXPECT_EQ(2, remove_count.value());
  EXPECT_TRUE(cb_reg.empty());
}

}  // namespace
}  // namespace base
