// Copyright 2016 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 <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "mojo/public/cpp/bindings/associated_binding.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr_info.h"
#include "mojo/public/cpp/bindings/associated_interface_request.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/interfaces/bindings/tests/test_associated_interfaces.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace mojo {
namespace test {
namespace {

class TestTaskRunner : public base::SingleThreadTaskRunner {
 public:
  TestTaskRunner()
      : thread_id_(base::PlatformThread::CurrentRef()),
        quit_called_(false),
        task_ready_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
                    base::WaitableEvent::InitialState::NOT_SIGNALED) {}

  bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
                                  base::OnceClosure task,
                                  base::TimeDelta delay) override {
    NOTREACHED();
    return false;
  }

  bool PostDelayedTask(const tracked_objects::Location& from_here,
                       base::OnceClosure task,
                       base::TimeDelta delay) override {
    {
      base::AutoLock locker(lock_);
      tasks_.push(std::move(task));
    }
    task_ready_.Signal();
    return true;
  }
  bool RunsTasksOnCurrentThread() const override {
    return base::PlatformThread::CurrentRef() == thread_id_;
  }

  // Only quits when Quit() is called.
  void Run() {
    DCHECK(RunsTasksOnCurrentThread());
    quit_called_ = false;

    while (true) {
      {
        base::AutoLock locker(lock_);
        while (!tasks_.empty()) {
          auto task = std::move(tasks_.front());
          tasks_.pop();

          {
            base::AutoUnlock unlocker(lock_);
            std::move(task).Run();
            if (quit_called_)
              return;
          }
        }
      }
      task_ready_.Wait();
    }
  }

  void Quit() {
    DCHECK(RunsTasksOnCurrentThread());
    quit_called_ = true;
  }

  // Waits until one task is ready and runs it.
  void RunOneTask() {
    DCHECK(RunsTasksOnCurrentThread());

    while (true) {
      {
        base::AutoLock locker(lock_);
        if (!tasks_.empty()) {
          auto task = std::move(tasks_.front());
          tasks_.pop();

          {
            base::AutoUnlock unlocker(lock_);
            std::move(task).Run();
            return;
          }
        }
      }
      task_ready_.Wait();
    }
  }

 private:
  ~TestTaskRunner() override {}

  const base::PlatformThreadRef thread_id_;
  bool quit_called_;
  base::WaitableEvent task_ready_;

  // Protect |tasks_|.
  base::Lock lock_;
  std::queue<base::OnceClosure> tasks_;

  DISALLOW_COPY_AND_ASSIGN(TestTaskRunner);
};

template <typename BindingType, typename RequestType>
class IntegerSenderImpl : public IntegerSender {
 public:
  IntegerSenderImpl(RequestType request,
                    scoped_refptr<base::SingleThreadTaskRunner> runner)
      : binding_(this, std::move(request), std::move(runner)) {}

  ~IntegerSenderImpl() override {}

  using EchoHandler = base::Callback<void(int32_t, const EchoCallback&)>;

  void set_echo_handler(const EchoHandler& handler) { echo_handler_ = handler; }

  void Echo(int32_t value, const EchoCallback& callback) override {
    if (echo_handler_.is_null())
      callback.Run(value);
    else
      echo_handler_.Run(value, callback);
  }
  void Send(int32_t value) override { NOTREACHED(); }

  BindingType* binding() { return &binding_; }

 private:
  BindingType binding_;
  EchoHandler echo_handler_;
};

class IntegerSenderConnectionImpl : public IntegerSenderConnection {
 public:
  using SenderType = IntegerSenderImpl<AssociatedBinding<IntegerSender>,
                                       IntegerSenderAssociatedRequest>;

  explicit IntegerSenderConnectionImpl(
      IntegerSenderConnectionRequest request,
      scoped_refptr<base::SingleThreadTaskRunner> runner,
      scoped_refptr<base::SingleThreadTaskRunner> sender_runner)
      : binding_(this, std::move(request), std::move(runner)),
        sender_runner_(std::move(sender_runner)) {}

  ~IntegerSenderConnectionImpl() override {}

  void set_get_sender_notification(const base::Closure& notification) {
    get_sender_notification_ = notification;
  }
  void GetSender(IntegerSenderAssociatedRequest sender) override {
    sender_impl_.reset(new SenderType(std::move(sender), sender_runner_));
    get_sender_notification_.Run();
  }

  void AsyncGetSender(const AsyncGetSenderCallback& callback) override {
    NOTREACHED();
  }

  Binding<IntegerSenderConnection>* binding() { return &binding_; }

  SenderType* sender_impl() { return sender_impl_.get(); }

 private:
  Binding<IntegerSenderConnection> binding_;
  std::unique_ptr<SenderType> sender_impl_;
  scoped_refptr<base::SingleThreadTaskRunner> sender_runner_;
  base::Closure get_sender_notification_;
};

class BindTaskRunnerTest : public testing::Test {
 protected:
  void SetUp() override {
    binding_task_runner_ = scoped_refptr<TestTaskRunner>(new TestTaskRunner);
    ptr_task_runner_ = scoped_refptr<TestTaskRunner>(new TestTaskRunner);

    auto request = MakeRequest(&ptr_, ptr_task_runner_);
    impl_.reset(new ImplType(std::move(request), binding_task_runner_));
  }

  base::MessageLoop loop_;
  scoped_refptr<TestTaskRunner> binding_task_runner_;
  scoped_refptr<TestTaskRunner> ptr_task_runner_;

  IntegerSenderPtr ptr_;
  using ImplType =
      IntegerSenderImpl<Binding<IntegerSender>, IntegerSenderRequest>;
  std::unique_ptr<ImplType> impl_;
};

class AssociatedBindTaskRunnerTest : public testing::Test {
 protected:
  void SetUp() override {
    connection_binding_task_runner_ =
        scoped_refptr<TestTaskRunner>(new TestTaskRunner);
    connection_ptr_task_runner_ =
        scoped_refptr<TestTaskRunner>(new TestTaskRunner);
    sender_binding_task_runner_ =
        scoped_refptr<TestTaskRunner>(new TestTaskRunner);
    sender_ptr_task_runner_ = scoped_refptr<TestTaskRunner>(new TestTaskRunner);

    auto connection_request =
        MakeRequest(&connection_ptr_, connection_ptr_task_runner_);
    connection_impl_.reset(new IntegerSenderConnectionImpl(
        std::move(connection_request), connection_binding_task_runner_,
        sender_binding_task_runner_));

    connection_impl_->set_get_sender_notification(
        base::Bind(&AssociatedBindTaskRunnerTest::QuitTaskRunner,
                   base::Unretained(this)));

    connection_ptr_->GetSender(
        MakeRequest(&sender_ptr_, sender_ptr_task_runner_));
    connection_binding_task_runner_->Run();
  }

  void QuitTaskRunner() {
    connection_binding_task_runner_->Quit();
  }

  base::MessageLoop loop_;
  scoped_refptr<TestTaskRunner> connection_binding_task_runner_;
  scoped_refptr<TestTaskRunner> connection_ptr_task_runner_;
  scoped_refptr<TestTaskRunner> sender_binding_task_runner_;
  scoped_refptr<TestTaskRunner> sender_ptr_task_runner_;

  IntegerSenderConnectionPtr connection_ptr_;
  std::unique_ptr<IntegerSenderConnectionImpl> connection_impl_;
  IntegerSenderAssociatedPtr sender_ptr_;
};

void DoSetFlagAndQuitTaskRunner(bool* flag,
                                scoped_refptr<TestTaskRunner> task_runner) {
  *flag = true;
  if (task_runner)
    task_runner->Quit();
}

void DoExpectValueSetFlagAndQuitTaskRunner(
    int32_t expected_value,
    bool* flag,
    scoped_refptr<TestTaskRunner> task_runner,
    int32_t value) {
  EXPECT_EQ(expected_value, value);
  DoSetFlagAndQuitTaskRunner(flag, task_runner);
}

void DoExpectValueSetFlagForwardValueAndQuitTaskRunner(
    int32_t expected_value,
    bool* flag,
    scoped_refptr<TestTaskRunner> task_runner,
    int32_t value,
    const IntegerSender::EchoCallback& callback) {
  EXPECT_EQ(expected_value, value);
  *flag = true;
  callback.Run(value);
  task_runner->Quit();
}

base::Closure SetFlagAndQuitTaskRunner(
    bool* flag,
    scoped_refptr<TestTaskRunner> task_runner) {
  return base::Bind(&DoSetFlagAndQuitTaskRunner, flag, task_runner);
}

base::Callback<void(int32_t)> ExpectValueSetFlagAndQuitTaskRunner(
    int32_t expected_value,
    bool* flag,
    scoped_refptr<TestTaskRunner> task_runner) {
  return base::Bind(&DoExpectValueSetFlagAndQuitTaskRunner, expected_value,
                    flag, task_runner);
}

TEST_F(BindTaskRunnerTest, MethodCall) {
  bool echo_called = false;
  impl_->set_echo_handler(
      base::Bind(&DoExpectValueSetFlagForwardValueAndQuitTaskRunner,
                 1024, &echo_called, binding_task_runner_));
  bool echo_replied = false;
  ptr_->Echo(1024, ExpectValueSetFlagAndQuitTaskRunner(1024, &echo_replied,
                                                       ptr_task_runner_));
  binding_task_runner_->Run();
  EXPECT_TRUE(echo_called);
  ptr_task_runner_->Run();
  EXPECT_TRUE(echo_replied);
}

TEST_F(BindTaskRunnerTest, BindingConnectionError) {
  bool connection_error_called = false;
  impl_->binding()->set_connection_error_handler(
      SetFlagAndQuitTaskRunner(&connection_error_called, binding_task_runner_));
  ptr_.reset();
  binding_task_runner_->Run();
  EXPECT_TRUE(connection_error_called);
}

TEST_F(BindTaskRunnerTest, PtrConnectionError) {
  bool connection_error_called = false;
  ptr_.set_connection_error_handler(
      SetFlagAndQuitTaskRunner(&connection_error_called, ptr_task_runner_));
  impl_->binding()->Close();
  ptr_task_runner_->Run();
  EXPECT_TRUE(connection_error_called);
}

void ExpectValueSetFlagAndForward(int32_t expected_value,
                                  bool* flag,
                                  int32_t value,
                                  const IntegerSender::EchoCallback& callback) {
  EXPECT_EQ(expected_value, value);
  *flag = true;
  callback.Run(value);
}

TEST_F(AssociatedBindTaskRunnerTest, MethodCall) {
  bool echo_called = false;
  connection_impl_->sender_impl()->set_echo_handler(
      base::Bind(&ExpectValueSetFlagAndForward, 1024, &echo_called));

  bool echo_replied = false;
  sender_ptr_->Echo(
      1024, ExpectValueSetFlagAndQuitTaskRunner(1024, &echo_replied, nullptr));

  // The Echo request first arrives at the master endpoint's task runner, and
  // then is forwarded to the associated endpoint's task runner.
  connection_binding_task_runner_->RunOneTask();
  sender_binding_task_runner_->RunOneTask();
  EXPECT_TRUE(echo_called);

  // Similarly, the Echo response arrives at the master endpoint's task runner
  // and then is forwarded to the associated endpoint's task runner.
  connection_ptr_task_runner_->RunOneTask();
  sender_ptr_task_runner_->RunOneTask();
  EXPECT_TRUE(echo_replied);
}

TEST_F(AssociatedBindTaskRunnerTest, BindingConnectionError) {
  bool sender_impl_error = false;
  connection_impl_->sender_impl()->binding()->set_connection_error_handler(
      SetFlagAndQuitTaskRunner(&sender_impl_error,
                               sender_binding_task_runner_));
  bool connection_impl_error = false;
  connection_impl_->binding()->set_connection_error_handler(
      SetFlagAndQuitTaskRunner(&connection_impl_error,
                               connection_binding_task_runner_));
  bool sender_ptr_error = false;
  sender_ptr_.set_connection_error_handler(
      SetFlagAndQuitTaskRunner(&sender_ptr_error, sender_ptr_task_runner_));
  connection_ptr_.reset();
  sender_ptr_task_runner_->Run();
  EXPECT_TRUE(sender_ptr_error);
  connection_binding_task_runner_->Run();
  EXPECT_TRUE(connection_impl_error);
  sender_binding_task_runner_->Run();
  EXPECT_TRUE(sender_impl_error);
}

TEST_F(AssociatedBindTaskRunnerTest, PtrConnectionError) {
  bool sender_impl_error = false;
  connection_impl_->sender_impl()->binding()->set_connection_error_handler(
      SetFlagAndQuitTaskRunner(&sender_impl_error,
                               sender_binding_task_runner_));
  bool connection_ptr_error = false;
  connection_ptr_.set_connection_error_handler(
      SetFlagAndQuitTaskRunner(&connection_ptr_error,
                               connection_ptr_task_runner_));
  bool sender_ptr_error = false;
  sender_ptr_.set_connection_error_handler(
      SetFlagAndQuitTaskRunner(&sender_ptr_error, sender_ptr_task_runner_));
  connection_impl_->binding()->Close();
  sender_binding_task_runner_->Run();
  EXPECT_TRUE(sender_impl_error);
  connection_ptr_task_runner_->Run();
  EXPECT_TRUE(connection_ptr_error);
  sender_ptr_task_runner_->Run();
  EXPECT_TRUE(sender_ptr_error);
}

}  // namespace
}  // namespace test
}  // namespace mojo
