// Copyright (c) 2012 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/message_loop_proxy_impl.h"

#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
#include "base/threading/thread.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"


class MessageLoopProxyImplTest : public testing::Test {
 public:
  void Release() const {
    AssertOnIOThread();
    Quit();
  }

  void Quit() const {
    loop_.PostTask(FROM_HERE, MessageLoop::QuitClosure());
  }

  void AssertOnIOThread() const {
    ASSERT_TRUE(io_thread_->message_loop_proxy()->BelongsToCurrentThread());
    ASSERT_EQ(io_thread_->message_loop_proxy(),
              base::MessageLoopProxy::current());
  }

  void AssertOnFileThread() const {
    ASSERT_TRUE(file_thread_->message_loop_proxy()->BelongsToCurrentThread());
    ASSERT_EQ(file_thread_->message_loop_proxy(),
              base::MessageLoopProxy::current());
  }

 protected:
  virtual void SetUp() OVERRIDE {
    io_thread_.reset(new base::Thread("MessageLoopProxyImplTest_IO"));
    file_thread_.reset(new base::Thread("MessageLoopProxyImplTest_File"));
    io_thread_->Start();
    file_thread_->Start();
  }

  virtual void TearDown() OVERRIDE {
    io_thread_->Stop();
    file_thread_->Stop();
  }

  static void BasicFunction(MessageLoopProxyImplTest* test) {
    test->AssertOnFileThread();
    test->Quit();
  }

  static void AssertNotRun() {
    FAIL() << "Callback Should not get executed.";
  }

  class DeletedOnFile {
   public:
    explicit DeletedOnFile(MessageLoopProxyImplTest* test) : test_(test) {}

    ~DeletedOnFile() {
      test_->AssertOnFileThread();
      test_->Quit();
    }

   private:
    MessageLoopProxyImplTest* test_;
  };

  scoped_ptr<base::Thread> io_thread_;
  scoped_ptr<base::Thread> file_thread_;

 private:
  mutable MessageLoop loop_;
};

TEST_F(MessageLoopProxyImplTest, Release) {
  EXPECT_TRUE(io_thread_->message_loop_proxy()->ReleaseSoon(FROM_HERE, this));
  MessageLoop::current()->Run();
}

TEST_F(MessageLoopProxyImplTest, Delete) {
  DeletedOnFile* deleted_on_file = new DeletedOnFile(this);
  EXPECT_TRUE(file_thread_->message_loop_proxy()->DeleteSoon(
      FROM_HERE, deleted_on_file));
  MessageLoop::current()->Run();
}

TEST_F(MessageLoopProxyImplTest, PostTask) {
  EXPECT_TRUE(file_thread_->message_loop_proxy()->PostTask(
      FROM_HERE, base::Bind(&MessageLoopProxyImplTest::BasicFunction,
                            base::Unretained(this))));
  MessageLoop::current()->Run();
}

TEST_F(MessageLoopProxyImplTest, PostTaskAfterThreadExits) {
  scoped_ptr<base::Thread> test_thread(
      new base::Thread("MessageLoopProxyImplTest_Dummy"));
  test_thread->Start();
  scoped_refptr<base::MessageLoopProxy> message_loop_proxy =
      test_thread->message_loop_proxy();
  test_thread->Stop();

  bool ret = message_loop_proxy->PostTask(
      FROM_HERE,
      base::Bind(&MessageLoopProxyImplTest::AssertNotRun));
  EXPECT_FALSE(ret);
}

TEST_F(MessageLoopProxyImplTest, PostTaskAfterThreadIsDeleted) {
  scoped_refptr<base::MessageLoopProxy> message_loop_proxy;
  {
    scoped_ptr<base::Thread> test_thread(
        new base::Thread("MessageLoopProxyImplTest_Dummy"));
    test_thread->Start();
    message_loop_proxy = test_thread->message_loop_proxy();
  }
  bool ret = message_loop_proxy->PostTask(
      FROM_HERE,
      base::Bind(&MessageLoopProxyImplTest::AssertNotRun));
  EXPECT_FALSE(ret);
}
