// 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 <map>
#include <string>

#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/simple_thread.h"
#include "base/threading/thread.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_globals.h"
#include "ppapi/proxy/plugin_proxy_delegate.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/plugin_var_tracker.h"
#include "ppapi/proxy/resource_message_test_sink.h"
#include "ppapi/shared_impl/test_globals.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
class MessageLoopProxy;
class RunLoop;
}

namespace ppapi {
namespace proxy {

class MessageLoopResource;

// Base class for plugin and host test harnesses. Tests will not use this
// directly. Instead, use the PluginProxyTest, HostProxyTest, or TwoWayTest.
class ProxyTestHarnessBase {
 public:
  enum GlobalsConfiguration {
    PER_THREAD_GLOBALS,
    SINGLETON_GLOBALS
  };

  ProxyTestHarnessBase();
  virtual ~ProxyTestHarnessBase();

  PP_Module pp_module() const { return pp_module_; }
  PP_Instance pp_instance() const { return pp_instance_; }
  ResourceMessageTestSink& sink() { return sink_; }

  virtual PpapiGlobals* GetGlobals() = 0;
  // Returns either the plugin or host dispatcher, depending on the test.
  virtual Dispatcher* GetDispatcher() = 0;

  // Set up the harness using an IPC::TestSink to capture messages.
  virtual void SetUpHarness() = 0;

  // Set up the harness using a real IPC channel.
  virtual void SetUpHarnessWithChannel(const IPC::ChannelHandle& channel_handle,
                                       base::MessageLoopProxy* ipc_message_loop,
                                       base::WaitableEvent* shutdown_event,
                                       bool is_client) = 0;

  virtual void TearDownHarness() = 0;

  // Implementation of GetInterface for the dispatcher. This will
  // return NULL for all interfaces unless one is registered by calling
  // RegisterTestInterface();
  const void* GetInterface(const char* name);

  // Allows the test to specify an interface implementation for a given
  // interface name. This will be returned when any of the proxy logic
  // requests a local interface.
  void RegisterTestInterface(const char* name, const void* test_interface);

  // Sends a "supports interface" message to the current dispatcher and returns
  // true if it's supported. This is just for the convenience of tests.
  bool SupportsInterface(const char* name);

 private:
  // Destination for IPC messages sent by the test.
  ResourceMessageTestSink sink_;

  // The module and instance ID associated with the plugin dispatcher.
  PP_Module pp_module_;
  PP_Instance pp_instance_;

  // Stores the data for GetInterface/RegisterTestInterface.
  std::map<std::string, const void*> registered_interfaces_;
};

// Test harness for the plugin side of the proxy.
class PluginProxyTestHarness : public ProxyTestHarnessBase {
 public:
  explicit PluginProxyTestHarness(GlobalsConfiguration globals_config);
  virtual ~PluginProxyTestHarness();

  PluginDispatcher* plugin_dispatcher() { return plugin_dispatcher_.get(); }
  PluginResourceTracker& resource_tracker() {
    return *plugin_globals_->plugin_resource_tracker();
  }
  PluginVarTracker& var_tracker() {
    return *plugin_globals_->plugin_var_tracker();
  }

  // ProxyTestHarnessBase implementation.
  virtual PpapiGlobals* GetGlobals();
  virtual Dispatcher* GetDispatcher();
  virtual void SetUpHarness();
  virtual void SetUpHarnessWithChannel(const IPC::ChannelHandle& channel_handle,
                                       base::MessageLoopProxy* ipc_message_loop,
                                       base::WaitableEvent* shutdown_event,
                                       bool is_client);
  virtual void TearDownHarness();

  class PluginDelegateMock : public PluginDispatcher::PluginDelegate,
                             public PluginProxyDelegate {
   public:
    PluginDelegateMock() : ipc_message_loop_(NULL), shutdown_event_() {}
    virtual ~PluginDelegateMock() {}

    void Init(base::MessageLoopProxy* ipc_message_loop,
              base::WaitableEvent* shutdown_event) {
      ipc_message_loop_ = ipc_message_loop;
      shutdown_event_ = shutdown_event;
    }

    void set_browser_sender(IPC::Sender* browser_sender) {
      browser_sender_ = browser_sender;
    }

    // ProxyChannel::Delegate implementation.
    virtual base::MessageLoopProxy* GetIPCMessageLoop() OVERRIDE;
    virtual base::WaitableEvent* GetShutdownEvent() OVERRIDE;
    virtual IPC::PlatformFileForTransit ShareHandleWithRemote(
        base::PlatformFile handle,
        base::ProcessId remote_pid,
        bool should_close_source) OVERRIDE;

    // PluginDispatcher::PluginDelegate implementation.
    virtual std::set<PP_Instance>* GetGloballySeenInstanceIDSet() OVERRIDE;
    virtual uint32 Register(PluginDispatcher* plugin_dispatcher) OVERRIDE;
    virtual void Unregister(uint32 plugin_dispatcher_id) OVERRIDE;

    // PluginProxyDelegate implementation.
    virtual IPC::Sender* GetBrowserSender() OVERRIDE;
    virtual std::string GetUILanguage() OVERRIDE;
    virtual void PreCacheFont(const void* logfontw) OVERRIDE;
    virtual void SetActiveURL(const std::string& url) OVERRIDE;
    virtual PP_Resource CreateBrowserFont(
        Connection connection,
        PP_Instance instance,
        const PP_BrowserFont_Trusted_Description& desc,
        const Preferences& prefs) OVERRIDE;

   private:
    base::MessageLoopProxy* ipc_message_loop_;  // Weak
    base::WaitableEvent* shutdown_event_;  // Weak
    std::set<PP_Instance> instance_id_set_;
    IPC::Sender* browser_sender_;

    DISALLOW_COPY_AND_ASSIGN(PluginDelegateMock);
  };

 private:
  void CreatePluginGlobals();

  GlobalsConfiguration globals_config_;
  scoped_ptr<PluginGlobals> plugin_globals_;

  scoped_ptr<PluginDispatcher> plugin_dispatcher_;
  PluginDelegateMock plugin_delegate_mock_;
};

class PluginProxyTest : public PluginProxyTestHarness, public testing::Test {
 public:
  PluginProxyTest();
  virtual ~PluginProxyTest();

  // testing::Test implementation.
  virtual void SetUp();
  virtual void TearDown();
 private:
  base::MessageLoop message_loop_;
};

// This class provides support for multi-thread testing. A secondary thread is
// created with a Pepper message loop.
// Subclasses need to implement the two SetUpTestOn*Thread() methods to do the
// actual testing work; and call both PostQuitFor*Thread() when testing is
// done.
class PluginProxyMultiThreadTest
    : public PluginProxyTest,
      public base::DelegateSimpleThread::Delegate {
 public:
  PluginProxyMultiThreadTest();
  virtual ~PluginProxyMultiThreadTest();

  // Called before the secondary thread is started, but after all the member
  // variables, including |secondary_thread_| and
  // |secondary_thread_message_loop_|, are initialized.
  virtual void SetUpTestOnMainThread() = 0;

  virtual void SetUpTestOnSecondaryThread() = 0;

  // TEST_F() should call this method.
  void RunTest();

  enum ThreadType {
    MAIN_THREAD,
    SECONDARY_THREAD
  };
  void CheckOnThread(ThreadType thread_type);

  // These can be called on any thread.
  void PostQuitForMainThread();
  void PostQuitForSecondaryThread();

 protected:
  scoped_refptr<MessageLoopResource> secondary_thread_message_loop_;
  scoped_refptr<base::MessageLoopProxy> main_thread_message_loop_proxy_;

 private:
  // base::DelegateSimpleThread::Delegate implementation.
  virtual void Run() OVERRIDE;

  void QuitNestedLoop();

  static void InternalSetUpTestOnSecondaryThread(void* user_data,
                                                 int32_t result);

  scoped_ptr<base::DelegateSimpleThread> secondary_thread_;
  scoped_ptr<base::RunLoop> nested_main_thread_message_loop_;
};

class HostProxyTestHarness : public ProxyTestHarnessBase {
 public:
  explicit HostProxyTestHarness(GlobalsConfiguration globals_config);
  virtual ~HostProxyTestHarness();

  HostDispatcher* host_dispatcher() { return host_dispatcher_.get(); }
  ResourceTracker& resource_tracker() {
    return *host_globals_->GetResourceTracker();
  }
  VarTracker& var_tracker() {
    return *host_globals_->GetVarTracker();
  }

  // ProxyTestBase implementation.
  virtual PpapiGlobals* GetGlobals();
  virtual Dispatcher* GetDispatcher();
  virtual void SetUpHarness();
  virtual void SetUpHarnessWithChannel(const IPC::ChannelHandle& channel_handle,
                                       base::MessageLoopProxy* ipc_message_loop,
                                       base::WaitableEvent* shutdown_event,
                                       bool is_client);
  virtual void TearDownHarness();

  class DelegateMock : public ProxyChannel::Delegate {
   public:
    DelegateMock() : ipc_message_loop_(NULL), shutdown_event_(NULL) {
    }
    virtual ~DelegateMock() {}

    void Init(base::MessageLoopProxy* ipc_message_loop,
              base::WaitableEvent* shutdown_event) {
      ipc_message_loop_ = ipc_message_loop;
      shutdown_event_ = shutdown_event;
    }

    // ProxyChannel::Delegate implementation.
    virtual base::MessageLoopProxy* GetIPCMessageLoop();
    virtual base::WaitableEvent* GetShutdownEvent();
    virtual IPC::PlatformFileForTransit ShareHandleWithRemote(
        base::PlatformFile handle,
        base::ProcessId remote_pid,
        bool should_close_source) OVERRIDE;

   private:
    base::MessageLoopProxy* ipc_message_loop_;  // Weak
    base::WaitableEvent* shutdown_event_;  // Weak

    DISALLOW_COPY_AND_ASSIGN(DelegateMock);
  };

 private:
  class MockSyncMessageStatusReceiver;

  void CreateHostGlobals();

  GlobalsConfiguration globals_config_;
  scoped_ptr<ppapi::TestGlobals> host_globals_;
  scoped_ptr<HostDispatcher> host_dispatcher_;
  DelegateMock delegate_mock_;

  scoped_ptr<MockSyncMessageStatusReceiver> status_receiver_;
};

class HostProxyTest : public HostProxyTestHarness, public testing::Test {
 public:
  HostProxyTest();
  virtual ~HostProxyTest();

  // testing::Test implementation.
  virtual void SetUp();
  virtual void TearDown();
 private:
  base::MessageLoop message_loop_;
};

// Use this base class to test both sides of a proxy.
class TwoWayTest : public testing::Test {
 public:
  enum TwoWayTestMode {
    TEST_PPP_INTERFACE,
    TEST_PPB_INTERFACE
  };
  TwoWayTest(TwoWayTestMode test_mode);
  virtual ~TwoWayTest();

  HostProxyTestHarness& host() { return host_; }
  PluginProxyTestHarness& plugin() { return plugin_; }
  PP_Module pp_module() const { return host_.pp_module(); }
  PP_Instance pp_instance() const { return host_.pp_instance(); }
  TwoWayTestMode test_mode() { return test_mode_; }

  // testing::Test implementation.
  virtual void SetUp();
  virtual void TearDown();

 protected:
  // Post a task to the thread where the remote harness lives. This
  // is typically used to test the state of the var tracker on the plugin
  // thread. This runs the task synchronously for convenience.
  void PostTaskOnRemoteHarness(const base::Closure& task);

 private:
  TwoWayTestMode test_mode_;
  HostProxyTestHarness host_;
  PluginProxyTestHarness plugin_;
  // In order to use sync IPC, we need to have an IO thread.
  base::Thread io_thread_;
  // The plugin side of the proxy runs on its own thread.
  base::Thread plugin_thread_;
  // The message loop for the main (host) thread.
  base::MessageLoop message_loop_;

  // Aliases for the host and plugin harnesses; if we're testing a PPP
  // interface, remote_harness will point to plugin_, and local_harness
  // will point to host_.  This makes it convenient when we're starting and
  // stopping the harnesses.
  ProxyTestHarnessBase* remote_harness_;
  ProxyTestHarnessBase* local_harness_;

  base::WaitableEvent channel_created_;
  base::WaitableEvent shutdown_event_;
};

// Used during Gtests when you have a PP_Var that you want to EXPECT is equal
// to a certain constant string value:
//
//   EXPECT_VAR_IS_STRING("foo", my_var);
#define EXPECT_VAR_IS_STRING(str, var) { \
  StringVar* sv = StringVar::FromPPVar(var); \
  EXPECT_TRUE(sv); \
  if (sv) \
    EXPECT_EQ(str, sv->value()); \
}

}  // namespace proxy
}  // namespace ppapi
