// 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 <gtest/gtest.h>
#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.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(Bind(&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
