// Copyright 2016 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 <stddef.h>

#include <new>
#include <utility>
#include <vector>

#include "base/macros.h"
#include "build/build_config.h"
#include "content/common/input/synthetic_web_input_event_builders.h"
#include "content/renderer/input/main_thread_event_queue.h"
#include "testing/gtest/include/gtest/gtest.h"

using blink::WebInputEvent;
using blink::WebMouseEvent;
using blink::WebMouseWheelEvent;
using blink::WebTouchEvent;

namespace content {
namespace {

const int kTestRoutingID = 13;
}

class MainThreadEventQueueTest : public testing::Test,
                                 public MainThreadEventQueueClient {
 public:
  MainThreadEventQueueTest() : queue_(kTestRoutingID, this) {}

  void SendEventToMainThread(int routing_id,
                             const blink::WebInputEvent* event,
                             const ui::LatencyInfo& latency,
                             InputEventDispatchType type) override {
    ASSERT_EQ(kTestRoutingID, routing_id);
    const unsigned char* eventPtr =
        reinterpret_cast<const unsigned char*>(event);
    last_event_.assign(eventPtr, eventPtr + event->size);
  }

  WebInputEventQueue<PendingMouseWheelEvent>& wheel_event_queue() {
    return queue_.wheel_events_;
  }

  WebInputEventQueue<PendingTouchEvent>& touch_event_queue() {
    return queue_.touch_events_;
  }

 protected:
  MainThreadEventQueue queue_;
  std::vector<unsigned char> last_event_;
};

TEST_F(MainThreadEventQueueTest, NonBlockingWheel) {
  WebMouseWheelEvent kEvents[4] = {
      SyntheticWebMouseWheelEventBuilder::Build(10, 10, 0, 53, 0, false),
      SyntheticWebMouseWheelEventBuilder::Build(20, 20, 0, 53, 0, false),
      SyntheticWebMouseWheelEventBuilder::Build(30, 30, 0, 53, 1, false),
      SyntheticWebMouseWheelEventBuilder::Build(30, 30, 0, 53, 1, false),
  };

  ASSERT_EQ(WebInputEventQueueState::ITEM_NOT_PENDING,
            wheel_event_queue().state());
  queue_.HandleEvent(&kEvents[0], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING,
                     INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
  ASSERT_EQ(WebInputEventQueueState::ITEM_PENDING, wheel_event_queue().state());
  queue_.HandleEvent(&kEvents[1], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING,
                     INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
  ASSERT_EQ(kEvents[0].size, last_event_.size());
  ASSERT_TRUE(memcmp(&last_event_[0], &kEvents[0], kEvents[0].size) == 0);
  queue_.EventHandled(blink::WebInputEvent::MouseWheel);
  ASSERT_EQ(kEvents[1].size, last_event_.size());
  ASSERT_TRUE(memcmp(&last_event_[0], &kEvents[1], kEvents[1].size) == 0);
  ASSERT_EQ(WebInputEventQueueState::ITEM_PENDING, wheel_event_queue().state());
  queue_.EventHandled(blink::WebInputEvent::MouseWheel);
  ASSERT_EQ(WebInputEventQueueState::ITEM_NOT_PENDING,
            wheel_event_queue().state());

  // Ensure that coalescing takes place.
  queue_.HandleEvent(&kEvents[0], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING,
                     INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
  queue_.HandleEvent(&kEvents[2], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING,
                     INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
  queue_.HandleEvent(&kEvents[3], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING,
                     INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
  ASSERT_EQ(1u, wheel_event_queue().size());
  ASSERT_EQ(WebInputEventQueueState::ITEM_PENDING, wheel_event_queue().state());
}

TEST_F(MainThreadEventQueueTest, NonBlockingTouch) {
  SyntheticWebTouchEvent kEvents[4];
  kEvents[0].PressPoint(10, 10);
  kEvents[1].PressPoint(10, 10);
  kEvents[1].modifiers = 1;
  kEvents[1].MovePoint(0, 20, 20);
  kEvents[2].PressPoint(10, 10);
  kEvents[2].MovePoint(0, 30, 30);
  kEvents[3].PressPoint(10, 10);
  kEvents[3].MovePoint(0, 35, 35);

  ASSERT_EQ(WebInputEventQueueState::ITEM_NOT_PENDING,
            touch_event_queue().state());
  queue_.HandleEvent(&kEvents[0], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING,
                     INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
  ASSERT_EQ(WebInputEventQueueState::ITEM_PENDING, touch_event_queue().state());
  queue_.HandleEvent(&kEvents[1], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING,
                     INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
  ASSERT_EQ(kEvents[0].size, last_event_.size());
  ASSERT_TRUE(memcmp(&last_event_[0], &kEvents[0], kEvents[0].size) == 0);
  queue_.EventHandled(blink::WebInputEvent::TouchStart);
  ASSERT_EQ(kEvents[1].size, last_event_.size());
  ASSERT_TRUE(memcmp(&last_event_[0], &kEvents[1], kEvents[1].size) == 0);
  ASSERT_EQ(WebInputEventQueueState::ITEM_PENDING, touch_event_queue().state());
  queue_.EventHandled(blink::WebInputEvent::TouchMove);
  ASSERT_EQ(WebInputEventQueueState::ITEM_NOT_PENDING,
            touch_event_queue().state());

  // Ensure that coalescing takes place.
  queue_.HandleEvent(&kEvents[0], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING,
                     INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
  queue_.HandleEvent(&kEvents[2], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING,
                     INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
  queue_.HandleEvent(&kEvents[3], ui::LatencyInfo(), DISPATCH_TYPE_BLOCKING,
                     INPUT_EVENT_ACK_STATE_SET_NON_BLOCKING);
  ASSERT_EQ(1u, touch_event_queue().size());
  ASSERT_EQ(WebInputEventQueueState::ITEM_PENDING, touch_event_queue().state());
}

}  // namespace content
