// 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 "ppapi/proxy/ppapi_proxy_test.h"

#include <sstream>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/observer_list.h"
#include "base/process/process_handle.h"
#include "base/run_loop.h"
#include "ipc/ipc_sync_channel.h"
#include "ipc/message_filter.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/private/ppb_proxy_private.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppb_message_loop_proxy.h"
#include "ppapi/shared_impl/proxy_lock.h"

namespace ppapi {
namespace proxy {

namespace {
// HostDispatcher requires a PPB_Proxy_Private, so we always provide a fallback
// do-nothing implementation.
void PluginCrashed(PP_Module module) {
  NOTREACHED();
};

PP_Instance GetInstanceForResource(PP_Resource resource) {
  // If a test relies on this, we need to implement it.
  NOTREACHED();
  return 0;
}

void SetReserveInstanceIDCallback(PP_Module module,
                                  PP_Bool (*is_seen)(PP_Module, PP_Instance)) {
  // This function gets called in HostDispatcher's constructor.  We simply don't
  // worry about Instance uniqueness in tests, so we can ignore the call.
}

void AddRefModule(PP_Module module) {}
void ReleaseModule(PP_Module module) {}
PP_Bool IsInModuleDestructor(PP_Module module) { return PP_FALSE; }

PPB_Proxy_Private ppb_proxy_private = {
  &PluginCrashed,
  &GetInstanceForResource,
  &SetReserveInstanceIDCallback,
  &AddRefModule,
  &ReleaseModule,
  &IsInModuleDestructor
};

// We allow multiple harnesses at a time to respond to 'GetInterface' calls.
// We assume that only 1 harness's GetInterface function will ever support a
// given interface name. In practice, there will either be only 1 GetInterface
// handler (for PluginProxyTest or HostProxyTest), or there will be only 2
// GetInterface handlers (for TwoWayTest).  In the latter case, one handler is
// for the PluginProxyTestHarness and should only respond for PPP interfaces,
// and the other handler is for the HostProxyTestHarness which should only
// ever respond for PPB interfaces.
ObserverList<ProxyTestHarnessBase> get_interface_handlers_;

const void* MockGetInterface(const char* name) {
  ObserverList<ProxyTestHarnessBase>::Iterator it =
      get_interface_handlers_;
  while (ProxyTestHarnessBase* observer = it.GetNext()) {
    const void* interface = observer->GetInterface(name);
    if (interface)
      return interface;
  }
  if (strcmp(name, PPB_PROXY_PRIVATE_INTERFACE) == 0)
    return &ppb_proxy_private;
  return NULL;
}

void SetUpRemoteHarness(ProxyTestHarnessBase* harness,
                        const IPC::ChannelHandle& handle,
                        base::MessageLoopProxy* ipc_message_loop_proxy,
                        base::WaitableEvent* shutdown_event,
                        base::WaitableEvent* harness_set_up) {
  harness->SetUpHarnessWithChannel(handle, ipc_message_loop_proxy,
                                   shutdown_event, false);
  harness_set_up->Signal();
}

void TearDownRemoteHarness(ProxyTestHarnessBase* harness,
                           base::WaitableEvent* harness_torn_down) {
  harness->TearDownHarness();
  harness_torn_down->Signal();
}

void RunTaskOnRemoteHarness(const base::Closure& task,
                            base::WaitableEvent* task_complete) {
 task.Run();
 task_complete->Signal();
}

}  // namespace

// ProxyTestHarnessBase --------------------------------------------------------

ProxyTestHarnessBase::ProxyTestHarnessBase() : pp_module_(0x98765),
                                               pp_instance_(0x12345) {
  get_interface_handlers_.AddObserver(this);
}

ProxyTestHarnessBase::~ProxyTestHarnessBase() {
  get_interface_handlers_.RemoveObserver(this);
}

const void* ProxyTestHarnessBase::GetInterface(const char* name) {
  return registered_interfaces_[name];
}

void ProxyTestHarnessBase::RegisterTestInterface(const char* name,
                                                 const void* test_interface) {
  registered_interfaces_[name] = test_interface;
}

bool ProxyTestHarnessBase::SupportsInterface(const char* name) {
  sink().ClearMessages();

  // IPC doesn't actually write to this when we send a message manually
  // not actually using IPC.
  bool unused_result = false;
  PpapiMsg_SupportsInterface msg(name, &unused_result);
  GetDispatcher()->OnMessageReceived(msg);

  const IPC::Message* reply_msg =
      sink().GetUniqueMessageMatching(IPC_REPLY_ID);
  EXPECT_TRUE(reply_msg);
  if (!reply_msg)
    return false;

  TupleTypes<PpapiMsg_SupportsInterface::ReplyParam>::ValueTuple reply_data;
  EXPECT_TRUE(PpapiMsg_SupportsInterface::ReadReplyParam(
      reply_msg, &reply_data));

  sink().ClearMessages();
  return get<0>(reply_data);
}

// PluginProxyTestHarness ------------------------------------------------------

PluginProxyTestHarness::PluginProxyTestHarness(
    GlobalsConfiguration globals_config)
    : globals_config_(globals_config) {
}

PluginProxyTestHarness::~PluginProxyTestHarness() {
}

PpapiGlobals* PluginProxyTestHarness::GetGlobals() {
  return plugin_globals_.get();
}

Dispatcher* PluginProxyTestHarness::GetDispatcher() {
  return plugin_dispatcher_.get();
}

void PluginProxyTestHarness::SetUpHarness() {
  // These must be first since the dispatcher set-up uses them.
  CreatePluginGlobals();
  // Some of the methods called during set-up check that the lock is held.
  ProxyAutoLock lock;

  resource_tracker().DidCreateInstance(pp_instance());

  plugin_dispatcher_.reset(new PluginDispatcher(
      &MockGetInterface,
      PpapiPermissions(),
      false));
  plugin_dispatcher_->InitWithTestSink(&sink());
  // The plugin proxy delegate is needed for
  // |PluginProxyDelegate::GetBrowserSender| which is used
  // in |ResourceCreationProxy::GetConnection| to get the channel to the
  // browser. In this case we just use the |plugin_dispatcher_| as the channel
  // for test purposes.
  plugin_delegate_mock_.set_browser_sender(plugin_dispatcher_.get());
  PluginGlobals::Get()->SetPluginProxyDelegate(&plugin_delegate_mock_);
  plugin_dispatcher_->DidCreateInstance(pp_instance());
}

void PluginProxyTestHarness::SetUpHarnessWithChannel(
    const IPC::ChannelHandle& channel_handle,
    base::MessageLoopProxy* ipc_message_loop,
    base::WaitableEvent* shutdown_event,
    bool is_client) {
  // These must be first since the dispatcher set-up uses them.
  CreatePluginGlobals();
  // Some of the methods called during set-up check that the lock is held.
  ProxyAutoLock lock;

  resource_tracker().DidCreateInstance(pp_instance());
  plugin_delegate_mock_.Init(ipc_message_loop, shutdown_event);

  plugin_dispatcher_.reset(new PluginDispatcher(
      &MockGetInterface,
      PpapiPermissions(),
      false));
  plugin_dispatcher_->InitPluginWithChannel(&plugin_delegate_mock_,
                                            base::kNullProcessId,
                                            channel_handle,
                                            is_client);
  plugin_delegate_mock_.set_browser_sender(plugin_dispatcher_.get());
  PluginGlobals::Get()->SetPluginProxyDelegate(&plugin_delegate_mock_);
  plugin_dispatcher_->DidCreateInstance(pp_instance());
}

void PluginProxyTestHarness::TearDownHarness() {
  {
    // Some of the methods called during tear-down check that the lock is held.
    ProxyAutoLock lock;

    plugin_dispatcher_->DidDestroyInstance(pp_instance());
    plugin_dispatcher_.reset();

    resource_tracker().DidDeleteInstance(pp_instance());
  }
  plugin_globals_.reset();
}

void PluginProxyTestHarness::CreatePluginGlobals() {
  if (globals_config_ == PER_THREAD_GLOBALS) {
    plugin_globals_.reset(new PluginGlobals(PpapiGlobals::PerThreadForTest()));
    PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
    // Enable locking in case some other unit test ran before us and disabled
    // locking.
    ProxyLock::EnableLockingOnThreadForTest();
  } else {
    plugin_globals_.reset(new PluginGlobals());
    ProxyLock::EnableLockingOnThreadForTest();
  }
}

base::MessageLoopProxy*
PluginProxyTestHarness::PluginDelegateMock::GetIPCMessageLoop() {
  return ipc_message_loop_;
}

base::WaitableEvent*
PluginProxyTestHarness::PluginDelegateMock::GetShutdownEvent() {
  return shutdown_event_;
}

IPC::PlatformFileForTransit
PluginProxyTestHarness::PluginDelegateMock::ShareHandleWithRemote(
    base::PlatformFile handle,
    base::ProcessId /* remote_pid */,
    bool should_close_source) {
  return IPC::GetFileHandleForProcess(handle,
                                      base::GetCurrentProcessHandle(),
                                      should_close_source);
}

std::set<PP_Instance>*
PluginProxyTestHarness::PluginDelegateMock::GetGloballySeenInstanceIDSet() {
  return &instance_id_set_;
}

uint32 PluginProxyTestHarness::PluginDelegateMock::Register(
    PluginDispatcher* plugin_dispatcher) {
  return 0;
}

void PluginProxyTestHarness::PluginDelegateMock::Unregister(
    uint32 plugin_dispatcher_id) {
}

IPC::Sender* PluginProxyTestHarness::PluginDelegateMock::GetBrowserSender() {
  return browser_sender_;
}

std::string PluginProxyTestHarness::PluginDelegateMock::GetUILanguage() {
  return std::string("en-US");
}

void PluginProxyTestHarness::PluginDelegateMock::PreCacheFont(
    const void* logfontw) {
}

void PluginProxyTestHarness::PluginDelegateMock::SetActiveURL(
    const std::string& url) {
}

PP_Resource PluginProxyTestHarness::PluginDelegateMock::CreateBrowserFont(
    Connection connection,
    PP_Instance instance,
    const PP_BrowserFont_Trusted_Description& desc,
    const Preferences& prefs) {
  return 0;
}

// PluginProxyTest -------------------------------------------------------------

PluginProxyTest::PluginProxyTest() : PluginProxyTestHarness(SINGLETON_GLOBALS) {
}

PluginProxyTest::~PluginProxyTest() {
}

void PluginProxyTest::SetUp() {
  SetUpHarness();
}

void PluginProxyTest::TearDown() {
  TearDownHarness();
}

// PluginProxyMultiThreadTest --------------------------------------------------

PluginProxyMultiThreadTest::PluginProxyMultiThreadTest() {
}

PluginProxyMultiThreadTest::~PluginProxyMultiThreadTest() {
}

void PluginProxyMultiThreadTest::RunTest() {
  main_thread_message_loop_proxy_ =
      PpapiGlobals::Get()->GetMainThreadMessageLoop();
  ASSERT_EQ(main_thread_message_loop_proxy_.get(),
            base::MessageLoopProxy::current().get());
  nested_main_thread_message_loop_.reset(new base::RunLoop());

  secondary_thread_.reset(new base::DelegateSimpleThread(
      this, "PluginProxyMultiThreadTest"));

  {
    ProxyAutoLock auto_lock;

    // MessageLoopResource assumes that the proxy lock has been acquired.
    secondary_thread_message_loop_ = new MessageLoopResource(pp_instance());

    ASSERT_EQ(PP_OK,
        secondary_thread_message_loop_->PostWork(
            PP_MakeCompletionCallback(
                &PluginProxyMultiThreadTest::InternalSetUpTestOnSecondaryThread,
                this),
            0));
  }

  SetUpTestOnMainThread();

  secondary_thread_->Start();
  nested_main_thread_message_loop_->Run();
  secondary_thread_->Join();

  {
    ProxyAutoLock auto_lock;

    // The destruction requires a valid PpapiGlobals instance, so we should
    // explicitly release it.
    secondary_thread_message_loop_ = NULL;
  }

  secondary_thread_.reset(NULL);
  nested_main_thread_message_loop_.reset(NULL);
  main_thread_message_loop_proxy_ = NULL;
}

void PluginProxyMultiThreadTest::CheckOnThread(ThreadType thread_type) {
  ProxyAutoLock auto_lock;
  if (thread_type == MAIN_THREAD) {
    ASSERT_TRUE(MessageLoopResource::GetCurrent()->is_main_thread_loop());
  } else {
    ASSERT_EQ(secondary_thread_message_loop_.get(),
              MessageLoopResource::GetCurrent());
  }
}

void PluginProxyMultiThreadTest::PostQuitForMainThread() {
  main_thread_message_loop_proxy_->PostTask(
      FROM_HERE,
      base::Bind(&PluginProxyMultiThreadTest::QuitNestedLoop,
                 base::Unretained(this)));
}

void PluginProxyMultiThreadTest::PostQuitForSecondaryThread() {
  ProxyAutoLock auto_lock;
  secondary_thread_message_loop_->PostQuit(PP_TRUE);
}

void PluginProxyMultiThreadTest::Run() {
  ProxyAutoLock auto_lock;
  ASSERT_EQ(PP_OK, secondary_thread_message_loop_->AttachToCurrentThread());
  ASSERT_EQ(PP_OK, secondary_thread_message_loop_->Run());
  secondary_thread_message_loop_->DetachFromThread();
}

void PluginProxyMultiThreadTest::QuitNestedLoop() {
  nested_main_thread_message_loop_->Quit();
}

// static
void PluginProxyMultiThreadTest::InternalSetUpTestOnSecondaryThread(
    void* user_data,
    int32_t result) {
  EXPECT_EQ(PP_OK, result);
  PluginProxyMultiThreadTest* thiz =
      static_cast<PluginProxyMultiThreadTest*>(user_data);
  thiz->CheckOnThread(SECONDARY_THREAD);
  thiz->SetUpTestOnSecondaryThread();
}

// HostProxyTestHarness --------------------------------------------------------

HostProxyTestHarness::HostProxyTestHarness(GlobalsConfiguration globals_config)
    : globals_config_(globals_config) {
}

HostProxyTestHarness::~HostProxyTestHarness() {
}

PpapiGlobals* HostProxyTestHarness::GetGlobals() {
  return host_globals_.get();
}

Dispatcher* HostProxyTestHarness::GetDispatcher() {
  return host_dispatcher_.get();
}

void HostProxyTestHarness::SetUpHarness() {
  // These must be first since the dispatcher set-up uses them.
  CreateHostGlobals();

  host_dispatcher_.reset(new HostDispatcher(
      pp_module(),
      &MockGetInterface,
      PpapiPermissions::AllPermissions()));
  host_dispatcher_->InitWithTestSink(&sink());
  HostDispatcher::SetForInstance(pp_instance(), host_dispatcher_.get());
}

void HostProxyTestHarness::SetUpHarnessWithChannel(
    const IPC::ChannelHandle& channel_handle,
    base::MessageLoopProxy* ipc_message_loop,
    base::WaitableEvent* shutdown_event,
    bool is_client) {
  // These must be first since the dispatcher set-up uses them.
  CreateHostGlobals();

  delegate_mock_.Init(ipc_message_loop, shutdown_event);

  host_dispatcher_.reset(new HostDispatcher(
      pp_module(),
      &MockGetInterface,
      PpapiPermissions::AllPermissions()));
  ppapi::Preferences preferences;
  host_dispatcher_->InitHostWithChannel(&delegate_mock_,
                                        base::kNullProcessId, channel_handle,
                                        is_client, preferences);
  HostDispatcher::SetForInstance(pp_instance(), host_dispatcher_.get());
}

void HostProxyTestHarness::TearDownHarness() {
  HostDispatcher::RemoveForInstance(pp_instance());
  host_dispatcher_.reset();
  host_globals_.reset();
}

void HostProxyTestHarness::CreateHostGlobals() {
  if (globals_config_ == PER_THREAD_GLOBALS) {
    host_globals_.reset(new TestGlobals(PpapiGlobals::PerThreadForTest()));
    PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
    // The host side of the proxy does not lock.
    ProxyLock::DisableLockingOnThreadForTest();
  } else {
    ProxyLock::DisableLockingOnThreadForTest();
    host_globals_.reset(new TestGlobals());
  }
}

base::MessageLoopProxy*
HostProxyTestHarness::DelegateMock::GetIPCMessageLoop() {
  return ipc_message_loop_;
}

base::WaitableEvent* HostProxyTestHarness::DelegateMock::GetShutdownEvent() {
  return shutdown_event_;
}

IPC::PlatformFileForTransit
HostProxyTestHarness::DelegateMock::ShareHandleWithRemote(
    base::PlatformFile handle,
    base::ProcessId /* remote_pid */,
    bool should_close_source) {
  return IPC::GetFileHandleForProcess(handle,
                                      base::GetCurrentProcessHandle(),
                                      should_close_source);
}


// HostProxyTest ---------------------------------------------------------------

HostProxyTest::HostProxyTest() : HostProxyTestHarness(SINGLETON_GLOBALS) {
}

HostProxyTest::~HostProxyTest() {
}

void HostProxyTest::SetUp() {
  SetUpHarness();
}

void HostProxyTest::TearDown() {
  TearDownHarness();
}

// TwoWayTest ---------------------------------------------------------------

TwoWayTest::TwoWayTest(TwoWayTest::TwoWayTestMode test_mode)
    : test_mode_(test_mode),
      host_(ProxyTestHarnessBase::PER_THREAD_GLOBALS),
      plugin_(ProxyTestHarnessBase::PER_THREAD_GLOBALS),
      io_thread_("TwoWayTest_IOThread"),
      plugin_thread_("TwoWayTest_PluginThread"),
      remote_harness_(NULL),
      local_harness_(NULL),
      channel_created_(true, false),
      shutdown_event_(true, false) {
  if (test_mode == TEST_PPP_INTERFACE) {
    remote_harness_ = &plugin_;
    local_harness_ = &host_;
  } else {
    remote_harness_ = &host_;
    local_harness_ = &plugin_;
  }
}

TwoWayTest::~TwoWayTest() {
  shutdown_event_.Signal();
}

void TwoWayTest::SetUp() {
  base::Thread::Options options;
  options.message_loop_type = base::MessageLoop::TYPE_IO;
  io_thread_.StartWithOptions(options);
  plugin_thread_.Start();

  // Construct the IPC handle name using the process ID so we can safely run
  // multiple |TwoWayTest|s concurrently.
  std::ostringstream handle_name;
  handle_name << "TwoWayTestChannel" << base::GetCurrentProcId();
  IPC::ChannelHandle handle(handle_name.str());
  base::WaitableEvent remote_harness_set_up(true, false);
  plugin_thread_.message_loop_proxy()->PostTask(
      FROM_HERE,
      base::Bind(&SetUpRemoteHarness,
                 remote_harness_,
                 handle,
                 io_thread_.message_loop_proxy(),
                 &shutdown_event_,
                 &remote_harness_set_up));
  remote_harness_set_up.Wait();
  local_harness_->SetUpHarnessWithChannel(handle,
                                          io_thread_.message_loop_proxy().get(),
                                          &shutdown_event_,
                                          true);  // is_client
}

void TwoWayTest::TearDown() {
  base::WaitableEvent remote_harness_torn_down(true, false);
  plugin_thread_.message_loop_proxy()->PostTask(
      FROM_HERE,
      base::Bind(&TearDownRemoteHarness,
                 remote_harness_,
                 &remote_harness_torn_down));
  remote_harness_torn_down.Wait();

  local_harness_->TearDownHarness();

  io_thread_.Stop();
}

void TwoWayTest::PostTaskOnRemoteHarness(const base::Closure& task) {
  base::WaitableEvent task_complete(true, false);
  plugin_thread_.message_loop_proxy()->PostTask(FROM_HERE,
      base::Bind(&RunTaskOnRemoteHarness,
                 task,
                 &task_complete));
  task_complete.Wait();
}


}  // namespace proxy
}  // namespace ppapi
