// 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/tests/test_input_event.h"

#include "ppapi/c/dev/ppb_testing_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_input_event.h"
#include "ppapi/cpp/input_event.h"
#include "ppapi/cpp/module.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"

REGISTER_TEST_CASE(InputEvent);

namespace {

const uint32_t kSpaceChar = 0x20;
const char* kSpaceString = " ";

#define FINISHED_WAITING_MESSAGE "TEST_INPUT_EVENT_FINISHED_WAITING"

pp::Point GetCenter(const pp::Rect& rect) {
  return pp::Point(
      rect.x() + rect.width() / 2,
      rect.y() + rect.height() / 2);
}

}  // namespace

void TestInputEvent::RunTests(const std::string& filter) {
  RUN_TEST(Events, filter);

  // The AcceptTouchEvent_N tests should not be run when the filter is empty;
  // they can only be run one at a time.
  // TODO(dmichael): Figure out a way to make these run in the same test fixture
  //                 instance.
  if (!ShouldRunAllTests(filter)) {
    RUN_TEST(AcceptTouchEvent_1, filter);
    RUN_TEST(AcceptTouchEvent_2, filter);
    RUN_TEST(AcceptTouchEvent_3, filter);
    RUN_TEST(AcceptTouchEvent_4, filter);
  }
}

TestInputEvent::TestInputEvent(TestingInstance* instance)
    : TestCase(instance),
      input_event_interface_(NULL),
      mouse_input_event_interface_(NULL),
      wheel_input_event_interface_(NULL),
      keyboard_input_event_interface_(NULL),
      touch_input_event_interface_(NULL),
      nested_event_(instance->pp_instance()),
      view_rect_(),
      expected_input_event_(0),
      received_expected_event_(false),
      received_finish_message_(false) {
}

TestInputEvent::~TestInputEvent() {
  // Remove the special listener that only responds to a
  // FINISHED_WAITING_MESSAGE string. See Init for where it gets added.
  std::string js_code;
  js_code += "var plugin = document.getElementById('plugin');"
             "plugin.removeEventListener('message',"
             "                           plugin.wait_for_messages_handler);"
             "delete plugin.wait_for_messages_handler;";
  instance_->EvalScript(js_code);
}

bool TestInputEvent::Init() {
  input_event_interface_ = static_cast<const PPB_InputEvent*>(
      pp::Module::Get()->GetBrowserInterface(PPB_INPUT_EVENT_INTERFACE));
  mouse_input_event_interface_ = static_cast<const PPB_MouseInputEvent*>(
      pp::Module::Get()->GetBrowserInterface(
          PPB_MOUSE_INPUT_EVENT_INTERFACE));
  wheel_input_event_interface_ = static_cast<const PPB_WheelInputEvent*>(
      pp::Module::Get()->GetBrowserInterface(
          PPB_WHEEL_INPUT_EVENT_INTERFACE));
  keyboard_input_event_interface_ = static_cast<const PPB_KeyboardInputEvent*>(
      pp::Module::Get()->GetBrowserInterface(
          PPB_KEYBOARD_INPUT_EVENT_INTERFACE));
  touch_input_event_interface_ = static_cast<const PPB_TouchInputEvent*>(
      pp::Module::Get()->GetBrowserInterface(
          PPB_TOUCH_INPUT_EVENT_INTERFACE));

  bool success =
      input_event_interface_ &&
      mouse_input_event_interface_ &&
      wheel_input_event_interface_ &&
      keyboard_input_event_interface_ &&
      touch_input_event_interface_ &&
      CheckTestingInterface();

  // Set up a listener for our message that signals that all input events have
  // been received.
  std::string js_code;
  // Note the following code is dependent on some features of test_case.html.
  // E.g., it is assumed that the DOM element where the plugin is embedded has
  // an id of 'plugin', and there is a function 'IsTestingMessage' that allows
  // us to ignore the messages that are intended for use by the testing
  // framework itself.
  js_code += "var plugin = document.getElementById('plugin');"
             "var wait_for_messages_handler = function(message_event) {"
             "  if (!IsTestingMessage(message_event.data) &&"
             "      message_event.data === '" FINISHED_WAITING_MESSAGE "') {"
             "    plugin.postMessage('" FINISHED_WAITING_MESSAGE "');"
             "  }"
             "};"
             "plugin.addEventListener('message', wait_for_messages_handler);"
             // Stash it on the plugin so we can remove it in the destructor.
             "plugin.wait_for_messages_handler = wait_for_messages_handler;";
  instance_->EvalScript(js_code);

  return success;
}

pp::InputEvent TestInputEvent::CreateMouseEvent(
    PP_InputEvent_Type type,
    PP_InputEvent_MouseButton buttons) {
  return pp::MouseInputEvent(
      instance_,
      type,
      100,  // time_stamp
      0,  // modifiers
      buttons,
      GetCenter(view_rect_),
      1,  // click count
      pp::Point());  // movement
}

pp::InputEvent TestInputEvent::CreateWheelEvent() {
  return pp::WheelInputEvent(
      instance_,
      100,  // time_stamp
      0,  // modifiers
      pp::FloatPoint(1, 2),
      pp::FloatPoint(3, 4),
      PP_TRUE);  // scroll_by_page
}

pp::InputEvent TestInputEvent::CreateKeyEvent(PP_InputEvent_Type type,
                                              uint32_t key_code) {
  return pp::KeyboardInputEvent(
      instance_,
      type,
      100,  // time_stamp
      0,  // modifiers
      key_code,
      pp::Var());
}

pp::InputEvent TestInputEvent::CreateCharEvent(const std::string& text) {
  return pp::KeyboardInputEvent(
      instance_,
      PP_INPUTEVENT_TYPE_CHAR,
      100,  // time_stamp
      0,  // modifiers
      0,  // keycode
      pp::Var(text));
}

pp::InputEvent TestInputEvent::CreateTouchEvent(PP_InputEvent_Type type,
                                                const pp::FloatPoint& point) {
  PP_TouchPoint touch_point = PP_MakeTouchPoint();
  touch_point.position = point;

  pp::TouchInputEvent touch_event(instance_, type, 100, 0);
  touch_event.AddTouchPoint(PP_TOUCHLIST_TYPE_TOUCHES, touch_point);
  touch_event.AddTouchPoint(PP_TOUCHLIST_TYPE_CHANGEDTOUCHES, touch_point);
  touch_event.AddTouchPoint(PP_TOUCHLIST_TYPE_TARGETTOUCHES, touch_point);

  return touch_event;
}

void TestInputEvent::PostMessageBarrier() {
  received_finish_message_ = false;
  instance_->PostMessage(pp::Var(FINISHED_WAITING_MESSAGE));
  testing_interface_->RunMessageLoop(instance_->pp_instance());
  nested_event_.Wait();
}

// Simulates the input event and calls PostMessage to let us know when
// we have received all resulting events from the browser.
bool TestInputEvent::SimulateInputEvent(
    const pp::InputEvent& input_event) {
  expected_input_event_ = pp::InputEvent(input_event.pp_resource());
  received_expected_event_ = false;
  testing_interface_->SimulateInputEvent(instance_->pp_instance(),
                                         input_event.pp_resource());
  PostMessageBarrier();
  return received_expected_event_;
}

bool TestInputEvent::AreEquivalentEvents(PP_Resource received,
                                         PP_Resource expected) {
  if (!input_event_interface_->IsInputEvent(received) ||
      !input_event_interface_->IsInputEvent(expected)) {
    return false;
  }

  // Test common fields, except modifiers and time stamp, which may be changed
  // by the browser.
  int32_t received_type = input_event_interface_->GetType(received);
  int32_t expected_type = input_event_interface_->GetType(expected);
  if (received_type != expected_type) {
    // Allow key down events to match "raw" key down events.
    if (expected_type != PP_INPUTEVENT_TYPE_KEYDOWN &&
        received_type != PP_INPUTEVENT_TYPE_RAWKEYDOWN) {
      return false;
    }
  }

  // Test event type-specific fields.
  switch (input_event_interface_->GetType(received)) {
    case PP_INPUTEVENT_TYPE_MOUSEDOWN:
    case PP_INPUTEVENT_TYPE_MOUSEUP:
    case PP_INPUTEVENT_TYPE_MOUSEMOVE:
    case PP_INPUTEVENT_TYPE_MOUSEENTER:
    case PP_INPUTEVENT_TYPE_MOUSELEAVE:
      // Check mouse fields, except position and movement, which may be
      // modified by the renderer.
      return
          mouse_input_event_interface_->GetButton(received) ==
          mouse_input_event_interface_->GetButton(expected) &&
          mouse_input_event_interface_->GetClickCount(received) ==
          mouse_input_event_interface_->GetClickCount(expected);

    case PP_INPUTEVENT_TYPE_WHEEL:
      return
          pp::FloatPoint(wheel_input_event_interface_->GetDelta(received)) ==
          pp::FloatPoint(wheel_input_event_interface_->GetDelta(expected)) &&
          pp::FloatPoint(wheel_input_event_interface_->GetTicks(received)) ==
          pp::FloatPoint(wheel_input_event_interface_->GetTicks(expected)) &&
          wheel_input_event_interface_->GetScrollByPage(received) ==
          wheel_input_event_interface_->GetScrollByPage(expected);

    case PP_INPUTEVENT_TYPE_RAWKEYDOWN:
    case PP_INPUTEVENT_TYPE_KEYDOWN:
    case PP_INPUTEVENT_TYPE_KEYUP:
      return
          keyboard_input_event_interface_->GetKeyCode(received) ==
          keyboard_input_event_interface_->GetKeyCode(expected);

    case PP_INPUTEVENT_TYPE_CHAR:
      return
          keyboard_input_event_interface_->GetKeyCode(received) ==
          keyboard_input_event_interface_->GetKeyCode(expected) &&
          pp::Var(pp::PASS_REF,
              keyboard_input_event_interface_->GetCharacterText(received)) ==
          pp::Var(pp::PASS_REF,
              keyboard_input_event_interface_->GetCharacterText(expected));

    case PP_INPUTEVENT_TYPE_TOUCHSTART:
    case PP_INPUTEVENT_TYPE_TOUCHMOVE:
    case PP_INPUTEVENT_TYPE_TOUCHEND:
    case PP_INPUTEVENT_TYPE_TOUCHCANCEL: {
      if (!touch_input_event_interface_->IsTouchInputEvent(received) ||
          !touch_input_event_interface_->IsTouchInputEvent(expected))
        return false;

      uint32_t touch_count = touch_input_event_interface_->GetTouchCount(
          received, PP_TOUCHLIST_TYPE_TOUCHES);
      if (touch_count <= 0 ||
          touch_count != touch_input_event_interface_->GetTouchCount(expected,
              PP_TOUCHLIST_TYPE_TOUCHES))
        return false;

      for (uint32_t i = 0; i < touch_count; ++i) {
        PP_TouchPoint expected_point = touch_input_event_interface_->
            GetTouchByIndex(expected, PP_TOUCHLIST_TYPE_TOUCHES, i);
        PP_TouchPoint received_point = touch_input_event_interface_->
            GetTouchByIndex(received, PP_TOUCHLIST_TYPE_TOUCHES, i);

        if (expected_point.id != received_point.id ||
            expected_point.radius != received_point.radius ||
            expected_point.rotation_angle != received_point.rotation_angle ||
            expected_point.pressure != received_point.pressure)
          return false;

        if (expected_point.position.x != received_point.position.x ||
            expected_point.position.y != received_point.position.y)
          return false;
      }
      return true;
    }

    default:
      break;
  }

  return false;
}

bool TestInputEvent::HandleInputEvent(const pp::InputEvent& input_event) {
  // Some events may cause extra events to be generated, so look for the
  // first one that matches.
  if (!received_expected_event_) {
    received_expected_event_ = AreEquivalentEvents(
        input_event.pp_resource(),
        expected_input_event_.pp_resource());
  }
  // Handle all input events.
  return true;
}

void TestInputEvent::HandleMessage(const pp::Var& message_data) {
  if (message_data.is_string() &&
      (message_data.AsString() == FINISHED_WAITING_MESSAGE)) {
    testing_interface_->QuitMessageLoop(instance_->pp_instance());
    received_finish_message_ = true;
    nested_event_.Signal();
  }
}

void TestInputEvent::DidChangeView(const pp::View& view) {
  view_rect_ = view.GetRect();
}

std::string TestInputEvent::TestEvents() {
  // Request all input event classes.
  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
                                             PP_INPUTEVENT_CLASS_MOUSE |
                                             PP_INPUTEVENT_CLASS_WHEEL |
                                             PP_INPUTEVENT_CLASS_KEYBOARD |
                                             PP_INPUTEVENT_CLASS_TOUCH);
  PostMessageBarrier();

  // Send the events and check that we received them.
  ASSERT_TRUE(
      SimulateInputEvent(CreateMouseEvent(PP_INPUTEVENT_TYPE_MOUSEDOWN,
                                          PP_INPUTEVENT_MOUSEBUTTON_LEFT)));
  ASSERT_TRUE(
      SimulateInputEvent(CreateWheelEvent()));
  ASSERT_TRUE(
      SimulateInputEvent(CreateKeyEvent(PP_INPUTEVENT_TYPE_KEYDOWN,
                                        kSpaceChar)));
  ASSERT_TRUE(
      SimulateInputEvent(CreateCharEvent(kSpaceString)));
  ASSERT_TRUE(SimulateInputEvent(CreateTouchEvent(PP_INPUTEVENT_TYPE_TOUCHSTART,
                                                  pp::FloatPoint(12, 23))));
  // Request only mouse events.
  input_event_interface_->ClearInputEventRequest(instance_->pp_instance(),
                                                 PP_INPUTEVENT_CLASS_WHEEL |
                                                 PP_INPUTEVENT_CLASS_KEYBOARD);
  PostMessageBarrier();

  // Check that we only receive mouse events.
  ASSERT_TRUE(
      SimulateInputEvent(CreateMouseEvent(PP_INPUTEVENT_TYPE_MOUSEDOWN,
                                          PP_INPUTEVENT_MOUSEBUTTON_LEFT)));
  ASSERT_FALSE(
      SimulateInputEvent(CreateWheelEvent()));
  ASSERT_FALSE(
      SimulateInputEvent(CreateKeyEvent(PP_INPUTEVENT_TYPE_KEYDOWN,
                                        kSpaceChar)));
  ASSERT_FALSE(
      SimulateInputEvent(CreateCharEvent(kSpaceString)));

  PASS();
}

std::string TestInputEvent::TestAcceptTouchEvent_1() {
  // The browser normally sends touch-events to the renderer only if the page
  // has touch-event handlers. Since test-case.html does not have any
  // touch-event handler, it would normally not receive any touch events from
  // the browser. However, if a plugin in the page does accept touch events,
  // then the browser should start sending touch-events to the page. In this
  // test, the plugin simply registers for touch-events. The real test is to
  // verify that the browser knows to send touch-events to the renderer.
  // If the plugin is removed from the page, then there are no more touch-event
  // handlers in the page, and browser stops sending touch-events. So to make
  // it possible to test this properly, the plugin is not removed from the page
  // at the end of the test.
  instance_->set_remove_plugin(false);
  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
                                             PP_INPUTEVENT_CLASS_MOUSE |
                                             PP_INPUTEVENT_CLASS_WHEEL |
                                             PP_INPUTEVENT_CLASS_KEYBOARD |
                                             PP_INPUTEVENT_CLASS_TOUCH);
  PASS();
}

std::string TestInputEvent::TestAcceptTouchEvent_2() {
  // See comment in TestAcceptTouchEvent_1.
  instance_->set_remove_plugin(false);
  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
                                             PP_INPUTEVENT_CLASS_MOUSE |
                                             PP_INPUTEVENT_CLASS_WHEEL |
                                             PP_INPUTEVENT_CLASS_KEYBOARD |
                                             PP_INPUTEVENT_CLASS_TOUCH);
  input_event_interface_->ClearInputEventRequest(instance_->pp_instance(),
                                                 PP_INPUTEVENT_CLASS_TOUCH);
  PASS();
}

std::string TestInputEvent::TestAcceptTouchEvent_3() {
  // See comment in TestAcceptTouchEvent_1.
  instance_->set_remove_plugin(false);
  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
                                             PP_INPUTEVENT_CLASS_MOUSE |
                                             PP_INPUTEVENT_CLASS_WHEEL |
                                             PP_INPUTEVENT_CLASS_KEYBOARD);
  input_event_interface_->RequestFilteringInputEvents(instance_->pp_instance(),
      PP_INPUTEVENT_CLASS_TOUCH);
  PASS();
}

std::string TestInputEvent::TestAcceptTouchEvent_4() {
  // See comment in TestAcceptTouchEvent_1.
  instance_->set_remove_plugin(false);
  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
                                             PP_INPUTEVENT_CLASS_MOUSE |
                                             PP_INPUTEVENT_CLASS_WHEEL |
                                             PP_INPUTEVENT_CLASS_KEYBOARD);
  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
                                             PP_INPUTEVENT_CLASS_TOUCH);
  PASS();
}

