// Copyright 2017 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 <functional>
#include <memory>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "chromecast/base/observer.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace chromecast {

class ObserverTest : public ::testing::Test {
 protected:
  ObserverTest() : message_loop_(std::make_unique<base::MessageLoop>()) {}

  const std::unique_ptr<base::MessageLoop> message_loop_;
};

struct NoDefaultConstructor {
  NoDefaultConstructor(int v) : value(v) {}

  int value;
};

class ThreadedObservable {
 public:
  ThreadedObservable() : thread_("ThreadedObservable"), value_(0) {
    thread_.Start();
  }

  Observer<int> Observe() { return value_.Observe(); }

  void SetValue(int value) {
    thread_.task_runner()->PostTask(
        FROM_HERE, base::BindOnce(&ThreadedObservable::SetValueOnThread,
                                  base::Unretained(this), value));
  }

 private:
  void SetValueOnThread(int value) {
    DCHECK(thread_.task_runner()->BelongsToCurrentThread());
    value_.SetValue(value);
  }

  base::Thread thread_;
  Observable<int> value_;

  DISALLOW_COPY_AND_ASSIGN(ThreadedObservable);
};

class ThreadedObserver {
 public:
  ThreadedObserver()
      : thread_("ThreadedObserver"),
        observing_(base::WaitableEvent::ResetPolicy::MANUAL,
                   base::WaitableEvent::InitialState::NOT_SIGNALED) {
    thread_.Start();
  }

  ~ThreadedObserver() {
    thread_.task_runner()->PostTask(
        FROM_HERE, base::BindOnce(&ThreadedObserver::DestroyOnThread,
                                  base::Unretained(this)));
    thread_.Stop();
  }

  void Observe(Observable<int>* observable) {
    thread_.task_runner()->PostTask(
        FROM_HERE, base::BindOnce(&ThreadedObserver::ObserveOnThread,
                                  base::Unretained(this), observable));
    observing_.Wait();
  }

  void CheckValue(int value) {
    thread_.task_runner()->PostTask(
        FROM_HERE, base::BindOnce(&ThreadedObserver::CheckValueOnThread,
                                  base::Unretained(this), value));
  }

 private:
  void ObserveOnThread(Observable<int>* observable) {
    DCHECK(thread_.task_runner()->BelongsToCurrentThread());
    observer_ = std::make_unique<Observer<int>>(observable->Observe());
    observing_.Signal();
  }

  void CheckValueOnThread(int value) {
    DCHECK(thread_.task_runner()->BelongsToCurrentThread());
    EXPECT_EQ(value, observer_->GetValue());
  }

  void DestroyOnThread() {
    DCHECK(thread_.task_runner()->BelongsToCurrentThread());
    observer_.reset();
  }

  base::Thread thread_;
  std::unique_ptr<Observer<int>> observer_;
  base::WaitableEvent observing_;

  DISALLOW_COPY_AND_ASSIGN(ThreadedObserver);
};

void RunCallback(std::function<void()> callback) {
  callback();
}

TEST_F(ObserverTest, SimpleValue) {
  Observable<int> original(0);
  Observer<int> observer = original.Observe();

  EXPECT_EQ(0, observer.GetValue());

  original.SetValue(1);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, observer.GetValue());
}

TEST_F(ObserverTest, MultipleObservers) {
  Observable<int> original(0);
  Observer<int> observer1 = original.Observe();
  Observer<int> observer2 = observer1;

  EXPECT_EQ(0, observer1.GetValue());
  EXPECT_EQ(0, observer2.GetValue());

  original.SetValue(1);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, observer1.GetValue());
  EXPECT_EQ(1, observer2.GetValue());
}

TEST_F(ObserverTest, NoDefaultConstructor) {
  Observable<NoDefaultConstructor> original(0);
  Observer<NoDefaultConstructor> observer = original.Observe();

  EXPECT_EQ(0, observer.GetValue().value);

  original.SetValue(1);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, observer.GetValue().value);
}

TEST_F(ObserverTest, NoMissingEvents) {
  Observable<int> original(0);
  Observer<int> observer = original.Observe();
  original.SetValue(1);

  std::vector<int> event_values;
  std::function<void()> callback = [&]() {
    event_values.push_back(observer.GetValue());
  };
  observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback));

  EXPECT_EQ(0, observer.GetValue());

  original.SetValue(2);
  base::RunLoop().RunUntilIdle();
  original.SetValue(3);
  original.SetValue(4);
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(4u, event_values.size());
  EXPECT_EQ(1, event_values[0]);
  EXPECT_EQ(2, event_values[1]);
  EXPECT_EQ(3, event_values[2]);
  EXPECT_EQ(4, event_values[3]);

  EXPECT_EQ(4, observer.GetValue());
}

TEST_F(ObserverTest, NoExtraEventsAfterChange) {
  Observable<int> original(0);
  original.SetValue(1);

  Observer<int> observer = original.Observe();
  EXPECT_EQ(1, observer.GetValue());

  std::vector<int> event_values;
  std::function<void()> callback = [&]() {
    event_values.push_back(observer.GetValue());
  };
  observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback));

  // Propagate the SetValue event; the observer shouldn't get it since it
  // started observing after SetValue().
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, observer.GetValue());
  EXPECT_EQ(0u, event_values.size());
}

TEST_F(ObserverTest, NoExtraEventsBetweenChanges) {
  Observable<int> original(0);
  original.SetValue(1);

  Observer<int> observer = original.Observe();
  EXPECT_EQ(1, observer.GetValue());

  original.SetValue(2);

  std::vector<int> event_values;
  std::function<void()> callback = [&]() {
    event_values.push_back(observer.GetValue());
  };
  observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback));

  // Propagate the SetValue events; the observer should only get the second
  // event, corresponding to the SetValue after the observer was created.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2, observer.GetValue());
  ASSERT_EQ(1u, event_values.size());
  EXPECT_EQ(2, event_values[0]);
}

TEST_F(ObserverTest, NoExtraEventsForCopy) {
  Observable<int> original(0);
  original.SetValue(1);

  Observer<int> observer1 = original.Observe();
  EXPECT_EQ(1, observer1.GetValue());

  original.SetValue(2);

  Observer<int> observer2 = observer1;
  // All observers on the same thread observe the same value. The update hasn't
  // propagated yet.
  EXPECT_EQ(1, observer2.GetValue());

  std::vector<int> event_values1;
  std::function<void()> callback1 = [&]() {
    event_values1.push_back(observer1.GetValue());
  };
  observer1.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback1));

  std::vector<int> event_values2;
  std::function<void()> callback2 = [&]() {
    event_values2.push_back(observer2.GetValue());
  };
  observer2.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback2));

  // Propagate the SetValue events; each observer should get just one callback
  // for the new value.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2, observer1.GetValue());
  EXPECT_EQ(2, observer2.GetValue());

  ASSERT_EQ(1u, event_values1.size());
  EXPECT_EQ(2, event_values1[0]);

  ASSERT_EQ(1u, event_values2.size());
  EXPECT_EQ(2, event_values2[0]);
}

TEST_F(ObserverTest, SetCallbackTwice) {
  Observable<int> original(0);
  original.SetValue(1);

  Observer<int> observer = original.Observe();
  EXPECT_EQ(1, observer.GetValue());

  original.SetValue(2);

  std::vector<int> event_values1;
  std::function<void()> callback1 = [&]() {
    event_values1.push_back(observer.GetValue());
  };
  observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback1));

  std::vector<int> event_values2;
  std::function<void()> callback2 = [&]() {
    event_values2.push_back(observer.GetValue());
  };
  observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback2));

  // Propagate the SetValue events; only the second callback should be run.
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(2, observer.GetValue());
  EXPECT_EQ(0u, event_values1.size());
  ASSERT_EQ(1u, event_values2.size());
  EXPECT_EQ(2, event_values2[0]);
}

TEST_F(ObserverTest, ObserverOutlivesObservable) {
  auto original = std::make_unique<Observable<int>>(0);
  Observer<int> observer1 = original->Observe();

  EXPECT_EQ(0, observer1.GetValue());

  original->SetValue(1);
  original.reset();

  Observer<int> observer2 = observer1;

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1, observer1.GetValue());
  EXPECT_EQ(1, observer2.GetValue());
}

TEST_F(ObserverTest, ObserverOnDifferentThread) {
  auto original = std::make_unique<ThreadedObservable>();
  Observer<int> observer = original->Observe();
  EXPECT_EQ(0, observer.GetValue());

  std::vector<int> event_values;
  std::function<void()> callback = [&]() {
    event_values.push_back(observer.GetValue());
  };
  observer.SetOnUpdateCallback(base::BindRepeating(&RunCallback, callback));

  original->SetValue(1);
  original->SetValue(2);
  original.reset();

  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(2, observer.GetValue());
  ASSERT_EQ(2u, event_values.size());
  EXPECT_EQ(1, event_values[0]);
  EXPECT_EQ(2, event_values[1]);
}

TEST_F(ObserverTest, ObserveOnManyThreads) {
  auto original = std::make_unique<Observable<int>>(0);
  std::vector<std::unique_ptr<ThreadedObserver>> observers;
  for (int i = 0; i < 20; ++i) {
    observers.push_back(std::make_unique<ThreadedObserver>());
    observers.back()->Observe(original.get());
  }

  original->SetValue(1);
  original.reset();

  base::RunLoop().RunUntilIdle();
  for (auto& observer : observers) {
    observer->CheckValue(1);
  }

  // Deleting the observers should check the expectations, since all posted
  // tasks on their internal threads will run.
  observers.clear();
}

}  // chromecast
