// 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/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 = " ";
const char* kSpaceCode = "Space";

#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);
  RUN_TEST(EventsLatencyTracking, 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),
      enable_latency_tracking_(false),
      last_latency_tracking_successful_(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));
  input_event_private_interface_ = static_cast<const PPB_InputEvent_Private*>(
      pp::Module::Get()->GetBrowserInterface(PPB_INPUTEVENT_PRIVATE_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_ &&
      input_event_private_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,
                                              const std::string& code) {
  return pp::KeyboardInputEvent(
      instance_,
      type,
      100,  // time_stamp
      0,  // modifiers
      key_code,
      pp::Var(),
      pp::Var(code));
}

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::Var());
}

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.
  if (enable_latency_tracking_) {
    pp::InputEventPrivate private_event(input_event);
    last_latency_tracking_successful_ = private_event.TraceInputLatency(true);
  }
  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::TestEventsLatencyTracking() {
  enable_latency_tracking_ = true;
  input_event_interface_->RequestInputEvents(instance_->pp_instance(),
                                             PP_INPUTEVENT_CLASS_TOUCH);
  PostMessageBarrier();

  ASSERT_TRUE(SimulateInputEvent(CreateTouchEvent(PP_INPUTEVENT_TYPE_TOUCHSTART,
                                                  pp::FloatPoint(12, 23))));
  // Without calling StartTrackingLatency() first, TraceInputLatency() won't
  // take effect and will return false;
  ASSERT_FALSE(last_latency_tracking_successful_);

  input_event_private_interface_->StartTrackingLatency(
      instance_->pp_instance());

  ASSERT_TRUE(SimulateInputEvent(CreateTouchEvent(PP_INPUTEVENT_TYPE_TOUCHSTART,
                                                  pp::FloatPoint(12, 23))));
  ASSERT_TRUE(last_latency_tracking_successful_);

  PASS();
}

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, kSpaceCode)));
  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, kSpaceCode)));
  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();
}
