// 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/synchronization/waitable_event.h"
#include "ipc/ipc_message_utils.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/ppb_fullscreen.h"
#include "ppapi/c/ppb_url_loader.h"
#include "ppapi/c/ppp_instance.h"
#include "ppapi/c/private/ppb_flash_fullscreen.h"
#include "ppapi/proxy/locking_resource_releaser.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppapi_proxy_test.h"
#include "ppapi/shared_impl/ppb_view_shared.h"

namespace ppapi {
namespace proxy {

namespace {
// This is a poor man's mock of PPP_Instance using global variables.  Eventually
// we should generalize making PPAPI interface mocks by using IDL or macro/
// template magic.
PP_Instance received_instance;
uint32_t received_argc;
std::vector<std::string> received_argn;
std::vector<std::string> received_argv;
PP_Bool bool_to_return;
PP_Bool DidCreate(PP_Instance instance, uint32_t argc, const char* argn[],
                  const char* argv[]) {
  received_instance = instance;
  received_argc = argc;
  received_argn.clear();
  received_argn.insert(received_argn.begin(), argn, argn + argc);
  received_argv.clear();
  received_argv.insert(received_argv.begin(), argv, argv + argc);
  return bool_to_return;
}

void DidDestroy(PP_Instance instance) {
  received_instance = instance;
}

PP_Rect received_position;
PP_Rect received_clip;
// DidChangeView is asynchronous. We wait until the call has completed before
// proceeding on to the next test.
base::WaitableEvent did_change_view_called(false, false);
void DidChangeView(PP_Instance instance, const PP_Rect* position,
                   const PP_Rect* clip) {
  received_instance = instance;
  received_position = *position;
  received_clip = *clip;
  did_change_view_called.Signal();
}

PP_Bool received_has_focus;
base::WaitableEvent did_change_focus_called(false, false);
void DidChangeFocus(PP_Instance instance, PP_Bool has_focus) {
  received_instance = instance;
  received_has_focus = has_focus;
  did_change_focus_called.Signal();
}

PP_Bool HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader) {
  // This one requires use of the PPB_URLLoader proxy and PPB_Core, plus a
  // resource tracker for the url_loader resource.
  // TODO(dmichael): Mock those out and test this function.
  NOTREACHED();
  return PP_FALSE;
}

// Clear all the 'received' values for our mock.  Call this before you expect
// one of the functions to be invoked.  TODO(dmichael): It would be better to
// have a flag also for each function, so we know the right one got called.
void ResetReceived() {
  received_instance = 0;
  received_argc = 0;
  received_argn.clear();
  received_argv.clear();
  memset(&received_position, 0, sizeof(received_position));
  memset(&received_clip, 0, sizeof(received_clip));
  received_has_focus = PP_FALSE;
}

PPP_Instance_1_0 ppp_instance_1_0 = {
  &DidCreate,
  &DidDestroy,
  &DidChangeView,
  &DidChangeFocus,
  &HandleDocumentLoad
};

// PPP_Instance_Proxy::DidChangeView relies on PPB_(Flash)Fullscreen being
// available with a valid implementation of IsFullScreen, so we mock it.
PP_Bool IsFullscreen(PP_Instance instance) {
  return PP_FALSE;
}
PPB_Fullscreen ppb_fullscreen = { &IsFullscreen };
PPB_FlashFullscreen ppb_flash_fullscreen = { &IsFullscreen };

}  // namespace

class PPP_Instance_ProxyTest : public TwoWayTest {
 public:
   PPP_Instance_ProxyTest()
       : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) {
   }
};

TEST_F(PPP_Instance_ProxyTest, PPPInstance1_0) {
  plugin().RegisterTestInterface(PPP_INSTANCE_INTERFACE_1_0, &ppp_instance_1_0);
  host().RegisterTestInterface(PPB_FLASHFULLSCREEN_INTERFACE,
                               &ppb_flash_fullscreen);
  host().RegisterTestInterface(PPB_FULLSCREEN_INTERFACE,
                               &ppb_fullscreen);

  // Grab the host-side proxy for the interface. The browser only speaks 1.1,
  // while the proxy ensures support for the 1.0 version on the plugin side.
  const PPP_Instance_1_1* ppp_instance = static_cast<const PPP_Instance_1_1*>(
      host().host_dispatcher()->GetProxiedInterface(
          PPP_INSTANCE_INTERFACE_1_1));

  // Call each function in turn, make sure we get the expected values and
  // returns.
  //
  // We don't test DidDestroy, because it has the side-effect of removing the
  // PP_Instance from the PluginDispatcher, which will cause a failure later
  // when the test is torn down.
  PP_Instance expected_instance = pp_instance();
  std::vector<std::string> expected_argn, expected_argv;
  expected_argn.push_back("Hello");
  expected_argn.push_back("world.");
  expected_argv.push_back("elloHay");
  expected_argv.push_back("orldway.");
  std::vector<const char*> argn_to_pass, argv_to_pass;
  CHECK(expected_argn.size() == expected_argv.size());
  for (size_t i = 0; i < expected_argn.size(); ++i) {
    argn_to_pass.push_back(expected_argn[i].c_str());
    argv_to_pass.push_back(expected_argv[i].c_str());
  }
  uint32_t expected_argc = expected_argn.size();
  bool_to_return = PP_TRUE;
  ResetReceived();
  // Tell the host resource tracker about the instance.
  host().resource_tracker().DidCreateInstance(expected_instance);
  EXPECT_EQ(bool_to_return, ppp_instance->DidCreate(expected_instance,
                                                    expected_argc,
                                                    &argn_to_pass[0],
                                                    &argv_to_pass[0]));
  EXPECT_EQ(received_instance, expected_instance);
  EXPECT_EQ(received_argc, expected_argc);
  EXPECT_EQ(received_argn, expected_argn);
  EXPECT_EQ(received_argv, expected_argv);

  PP_Rect expected_position = { {1, 2}, {3, 4} };
  PP_Rect expected_clip = { {5, 6}, {7, 8} };
  ViewData data;
  data.rect = expected_position;
  data.is_fullscreen = false;
  data.is_page_visible = true;
  data.clip_rect = expected_clip;
  data.device_scale = 1.0f;
  ResetReceived();
  LockingResourceReleaser view_resource(
      (new PPB_View_Shared(OBJECT_IS_IMPL,
                           expected_instance, data))->GetReference());
  ppp_instance->DidChangeView(expected_instance, view_resource.get());
  did_change_view_called.Wait();
  EXPECT_EQ(received_instance, expected_instance);
  EXPECT_EQ(received_position.point.x, expected_position.point.x);
  EXPECT_EQ(received_position.point.y, expected_position.point.y);
  EXPECT_EQ(received_position.size.width, expected_position.size.width);
  EXPECT_EQ(received_position.size.height, expected_position.size.height);
  EXPECT_EQ(received_clip.point.x, expected_clip.point.x);
  EXPECT_EQ(received_clip.point.y, expected_clip.point.y);
  EXPECT_EQ(received_clip.size.width, expected_clip.size.width);
  EXPECT_EQ(received_clip.size.height, expected_clip.size.height);

  PP_Bool expected_has_focus = PP_TRUE;
  ResetReceived();
  ppp_instance->DidChangeFocus(expected_instance, expected_has_focus);
  did_change_focus_called.Wait();
  EXPECT_EQ(received_instance, expected_instance);
  EXPECT_EQ(received_has_focus, expected_has_focus);

  //  TODO(dmichael): Need to mock out a resource Tracker to be able to test
  //                  HandleResourceLoad. It also requires
  //                  PPB_Core.AddRefResource and for PPB_URLLoader to be
  //                  registered.

  host().resource_tracker().DidDeleteInstance(expected_instance);
}

}  // namespace proxy
}  // namespace ppapi
