/*
 *  Copyright 2012 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/third_party/sigslot/sigslot.h"

#include "rtc_base/sigslot_repeater.h"
#include "test/gtest.h"

// This function, when passed a has_slots or signalx, will break the build if
// its threading requirement is not single threaded
static bool TemplateIsST(const sigslot::single_threaded* p) {
  return true;
}
// This function, when passed a has_slots or signalx, will break the build if
// its threading requirement is not multi threaded
static bool TemplateIsMT(const sigslot::multi_threaded_local* p) {
  return true;
}

class SigslotDefault : public testing::Test, public sigslot::has_slots<> {
 protected:
  sigslot::signal0<> signal_;
};

template <class slot_policy = sigslot::single_threaded,
          class signal_policy = sigslot::single_threaded>
class SigslotReceiver : public sigslot::has_slots<slot_policy> {
 public:
  SigslotReceiver() : signal_(nullptr), signal_count_(0) {}
  ~SigslotReceiver() {}

  // Provide copy constructor so that tests can exercise the has_slots copy
  // constructor.
  SigslotReceiver(const SigslotReceiver&) = default;

  void Connect(sigslot::signal0<signal_policy>* signal) {
    if (!signal)
      return;
    Disconnect();
    signal_ = signal;
    signal->connect(this,
                    &SigslotReceiver<slot_policy, signal_policy>::OnSignal);
  }
  void Disconnect() {
    if (!signal_)
      return;
    signal_->disconnect(this);
    signal_ = nullptr;
  }
  void OnSignal() { ++signal_count_; }
  int signal_count() { return signal_count_; }

 private:
  sigslot::signal0<signal_policy>* signal_;
  int signal_count_;
};

template <class slot_policy = sigslot::single_threaded,
          class mt_signal_policy = sigslot::multi_threaded_local>
class SigslotSlotTest : public testing::Test {
 protected:
  SigslotSlotTest() {
    mt_signal_policy mt_policy;
    TemplateIsMT(&mt_policy);
  }

  virtual void SetUp() { Connect(); }
  virtual void TearDown() { Disconnect(); }

  void Disconnect() {
    st_receiver_.Disconnect();
    mt_receiver_.Disconnect();
  }

  void Connect() {
    st_receiver_.Connect(&SignalSTLoopback);
    mt_receiver_.Connect(&SignalMTLoopback);
  }

  int st_loop_back_count() { return st_receiver_.signal_count(); }
  int mt_loop_back_count() { return mt_receiver_.signal_count(); }

  sigslot::signal0<> SignalSTLoopback;
  SigslotReceiver<slot_policy, sigslot::single_threaded> st_receiver_;
  sigslot::signal0<mt_signal_policy> SignalMTLoopback;
  SigslotReceiver<slot_policy, mt_signal_policy> mt_receiver_;
};

typedef SigslotSlotTest<> SigslotSTSlotTest;
typedef SigslotSlotTest<sigslot::multi_threaded_local,
                        sigslot::multi_threaded_local>
    SigslotMTSlotTest;

class multi_threaded_local_fake : public sigslot::multi_threaded_local {
 public:
  multi_threaded_local_fake() : lock_count_(0), unlock_count_(0) {}

  void lock() { ++lock_count_; }
  void unlock() { ++unlock_count_; }

  int lock_count() { return lock_count_; }

  bool InCriticalSection() { return lock_count_ != unlock_count_; }

 protected:
  int lock_count_;
  int unlock_count_;
};

typedef SigslotSlotTest<multi_threaded_local_fake, multi_threaded_local_fake>
    SigslotMTLockBase;

class SigslotMTLockTest : public SigslotMTLockBase {
 protected:
  SigslotMTLockTest() {}

  void SetUp() override {
    EXPECT_EQ(0, SlotLockCount());
    SigslotMTLockBase::SetUp();
    // Connects to two signals (ST and MT). However,
    // SlotLockCount() only gets the count for the
    // MT signal (there are two separate SigslotReceiver which
    // keep track of their own count).
    EXPECT_EQ(1, SlotLockCount());
  }
  void TearDown() override {
    const int previous_lock_count = SlotLockCount();
    SigslotMTLockBase::TearDown();
    // Disconnects from two signals. Note analogous to SetUp().
    EXPECT_EQ(previous_lock_count + 1, SlotLockCount());
  }

  int SlotLockCount() { return mt_receiver_.lock_count(); }
  void Signal() { SignalMTLoopback(); }
  int SignalLockCount() { return SignalMTLoopback.lock_count(); }
  int signal_count() { return mt_loop_back_count(); }
  bool InCriticalSection() { return SignalMTLoopback.InCriticalSection(); }
};

// This test will always succeed. However, if the default template instantiation
// changes from single threaded to multi threaded it will break the build here.
TEST_F(SigslotDefault, DefaultIsST) {
  EXPECT_TRUE(TemplateIsST(this));
  EXPECT_TRUE(TemplateIsST(&signal_));
}

// ST slot, ST signal
TEST_F(SigslotSTSlotTest, STLoopbackTest) {
  SignalSTLoopback();
  EXPECT_EQ(1, st_loop_back_count());
  EXPECT_EQ(0, mt_loop_back_count());
}

// ST slot, MT signal
TEST_F(SigslotSTSlotTest, MTLoopbackTest) {
  SignalMTLoopback();
  EXPECT_EQ(1, mt_loop_back_count());
  EXPECT_EQ(0, st_loop_back_count());
}

// ST slot, both ST and MT (separate) signal
TEST_F(SigslotSTSlotTest, AllLoopbackTest) {
  SignalSTLoopback();
  SignalMTLoopback();
  EXPECT_EQ(1, mt_loop_back_count());
  EXPECT_EQ(1, st_loop_back_count());
}

TEST_F(SigslotSTSlotTest, Reconnect) {
  SignalSTLoopback();
  SignalMTLoopback();
  EXPECT_EQ(1, mt_loop_back_count());
  EXPECT_EQ(1, st_loop_back_count());
  Disconnect();
  SignalSTLoopback();
  SignalMTLoopback();
  EXPECT_EQ(1, mt_loop_back_count());
  EXPECT_EQ(1, st_loop_back_count());
  Connect();
  SignalSTLoopback();
  SignalMTLoopback();
  EXPECT_EQ(2, mt_loop_back_count());
  EXPECT_EQ(2, st_loop_back_count());
}

// MT slot, ST signal
TEST_F(SigslotMTSlotTest, STLoopbackTest) {
  SignalSTLoopback();
  EXPECT_EQ(1, st_loop_back_count());
  EXPECT_EQ(0, mt_loop_back_count());
}

// MT slot, MT signal
TEST_F(SigslotMTSlotTest, MTLoopbackTest) {
  SignalMTLoopback();
  EXPECT_EQ(1, mt_loop_back_count());
  EXPECT_EQ(0, st_loop_back_count());
}

// MT slot, both ST and MT (separate) signal
TEST_F(SigslotMTSlotTest, AllLoopbackTest) {
  SignalMTLoopback();
  SignalSTLoopback();
  EXPECT_EQ(1, st_loop_back_count());
  EXPECT_EQ(1, mt_loop_back_count());
}

// Test that locks are acquired and released correctly.
TEST_F(SigslotMTLockTest, LockSanity) {
  const int lock_count = SignalLockCount();
  Signal();
  EXPECT_FALSE(InCriticalSection());
  EXPECT_EQ(lock_count + 1, SignalLockCount());
  EXPECT_EQ(1, signal_count());
}

// Destroy signal and slot in different orders.
TEST(SigslotDestructionOrder, SignalFirst) {
  sigslot::signal0<>* signal = new sigslot::signal0<>;
  SigslotReceiver<>* receiver = new SigslotReceiver<>();
  receiver->Connect(signal);
  (*signal)();
  EXPECT_EQ(1, receiver->signal_count());
  delete signal;
  delete receiver;
}

TEST(SigslotDestructionOrder, SlotFirst) {
  sigslot::signal0<>* signal = new sigslot::signal0<>;
  SigslotReceiver<>* receiver = new SigslotReceiver<>();
  receiver->Connect(signal);
  (*signal)();
  EXPECT_EQ(1, receiver->signal_count());

  delete receiver;
  (*signal)();
  delete signal;
}

// Test that if a signal is copied, its slot connections are copied as well.
TEST(SigslotTest, CopyConnectedSignal) {
  sigslot::signal<> signal;
  SigslotReceiver<> receiver;
  receiver.Connect(&signal);

  // Fire the copied signal, expecting the receiver to be notified.
  sigslot::signal<> copied_signal(signal);
  copied_signal();
  EXPECT_EQ(1, receiver.signal_count());
}

// Test that if a slot is copied, its signal connections are copied as well.
TEST(SigslotTest, CopyConnectedSlot) {
  sigslot::signal<> signal;
  SigslotReceiver<> receiver;
  receiver.Connect(&signal);

  // Fire the signal after copying the receiver, expecting the copied receiver
  // to be notified.
  SigslotReceiver<> copied_receiver(receiver);
  signal();
  EXPECT_EQ(1, copied_receiver.signal_count());
}

// Just used for the test below.
class Disconnector : public sigslot::has_slots<> {
 public:
  Disconnector(SigslotReceiver<>* receiver1, SigslotReceiver<>* receiver2)
      : receiver1_(receiver1), receiver2_(receiver2) {}

  void Connect(sigslot::signal<>* signal) {
    signal_ = signal;
    signal->connect(this, &Disconnector::Disconnect);
  }

 private:
  void Disconnect() {
    receiver1_->Disconnect();
    receiver2_->Disconnect();
    signal_->disconnect(this);
  }

  sigslot::signal<>* signal_;
  SigslotReceiver<>* receiver1_;
  SigslotReceiver<>* receiver2_;
};

// Test that things work as expected if a signal is disconnected from a slot
// while it's firing.
TEST(SigslotTest, DisconnectFromSignalWhileFiring) {
  sigslot::signal<> signal;
  SigslotReceiver<> receiver1;
  SigslotReceiver<> receiver2;
  SigslotReceiver<> receiver3;
  Disconnector disconnector(&receiver1, &receiver2);

  // From this ordering, receiver1 should receive the signal, then the
  // disconnector will be invoked, causing receiver2 to be disconnected before
  // it receives the signal. And receiver3 should also receive the signal,
  // since it was never disconnected.
  receiver1.Connect(&signal);
  disconnector.Connect(&signal);
  receiver2.Connect(&signal);
  receiver3.Connect(&signal);
  signal();

  EXPECT_EQ(1, receiver1.signal_count());
  EXPECT_EQ(0, receiver2.signal_count());
  EXPECT_EQ(1, receiver3.signal_count());
}

// Uses disconnect_all instead of disconnect.
class Disconnector2 : public sigslot::has_slots<> {
 public:
  void Connect(sigslot::signal<>* signal) {
    signal_ = signal;
    signal->connect(this, &Disconnector2::Disconnect);
  }

 private:
  void Disconnect() { signal_->disconnect_all(); }

  sigslot::signal<>* signal_;
};

// Test that things work as expected if a signal is disconnected from a slot
// while it's firing using disconnect_all.
TEST(SigslotTest, CallDisconnectAllWhileSignalFiring) {
  sigslot::signal<> signal;
  SigslotReceiver<> receiver1;
  SigslotReceiver<> receiver2;
  Disconnector2 disconnector;

  // From this ordering, receiver1 should receive the signal, then the
  // disconnector will be invoked, causing receiver2 to be disconnected before
  // it receives the signal.
  receiver1.Connect(&signal);
  disconnector.Connect(&signal);
  receiver2.Connect(&signal);
  signal();

  EXPECT_EQ(1, receiver1.signal_count());
  EXPECT_EQ(0, receiver2.signal_count());
}

// Basic test that a sigslot repeater works.
TEST(SigslotRepeaterTest, RepeatsSignalsAfterRepeatCalled) {
  sigslot::signal<> signal;
  sigslot::repeater<> repeater;
  repeater.repeat(signal);
  // Note that receiver is connected to the repeater, not directly to the
  // source signal.
  SigslotReceiver<> receiver;
  receiver.Connect(&repeater);
  // The repeater should repeat the signal, causing the receiver to see it.
  signal();
  EXPECT_EQ(1, receiver.signal_count());
  // Repeat another signal for good measure.
  signal();
  EXPECT_EQ(2, receiver.signal_count());
}

// After calling "stop", a repeater should stop repeating signals.
TEST(SigslotRepeaterTest, StopsRepeatingSignalsAfterStopCalled) {
  // Same setup as above test.
  sigslot::signal<> signal;
  sigslot::repeater<> repeater;
  repeater.repeat(signal);
  SigslotReceiver<> receiver;
  receiver.Connect(&repeater);
  signal();
  ASSERT_EQ(1, receiver.signal_count());
  // Now call stop. The next signal should NOT propagate to the receiver.
  repeater.stop(signal);
  signal();
  EXPECT_EQ(1, receiver.signal_count());
}
