// Copyright 2014 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 <stdint.h>

#include <memory>

#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "content/browser/renderer_host/input/input_ack_handler.h"
#include "content/browser/renderer_host/input/input_router_client.h"
#include "content/browser/renderer_host/input/input_router_impl.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
#include "content/public/common/content_features.h"
#include "ipc/ipc_sender.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/perf/perf_test.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/blink/web_input_event_traits.h"
#include "ui/gfx/geometry/vector2d_f.h"

using base::TimeDelta;
using blink::WebGestureEvent;
using blink::WebInputEvent;
using blink::WebTouchEvent;
using blink::WebTouchPoint;

namespace content {

namespace {

class NullInputAckHandler : public InputAckHandler {
 public:
  NullInputAckHandler() : ack_count_(0) {}
  ~NullInputAckHandler() override {}

  // InputAckHandler
  void OnKeyboardEventAck(const NativeWebKeyboardEventWithLatencyInfo& event,
                          InputEventAckState ack_result) override {
    ++ack_count_;
  }
  void OnMouseEventAck(const MouseEventWithLatencyInfo& event,
                       InputEventAckState ack_result) override {
    ++ack_count_;
  }
  void OnWheelEventAck(const MouseWheelEventWithLatencyInfo& event,
                       InputEventAckState ack_result) override {
    ++ack_count_;
  }
  void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
                       InputEventAckState ack_result) override {
    ++ack_count_;
  }
  void OnGestureEventAck(const GestureEventWithLatencyInfo& event,
                         InputEventAckState ack_result) override {
    ++ack_count_;
  }
  void OnUnexpectedEventAck(UnexpectedEventAckType type) override {
    ++ack_count_;
  }

  size_t GetAndResetAckCount() {
    size_t ack_count = ack_count_;
    ack_count_ = 0;
    return ack_count;
  }

  size_t ack_count() const { return ack_count_; }

 private:
  size_t ack_count_;
};

class NullInputRouterClient : public InputRouterClient {
 public:
  NullInputRouterClient() {}
  ~NullInputRouterClient() override {}

  // InputRouterClient
  InputEventAckState FilterInputEvent(
      const blink::WebInputEvent& input_event,
      const ui::LatencyInfo& latency_info) override {
    return INPUT_EVENT_ACK_STATE_NOT_CONSUMED;
  }
  void IncrementInFlightEventCount(
      blink::WebInputEvent::Type event_type) override {}
  void DecrementInFlightEventCount(InputEventAckSource ack_source) override {}
  void OnHasTouchEventHandlers(bool has_handlers) override {}
  void DidFlush() override {}
  void DidOverscroll(const ui::DidOverscrollParams& params) override {}
  void DidStopFlinging() override {}
  void ForwardGestureEventWithLatencyInfo(
      const blink::WebGestureEvent& event,
      const ui::LatencyInfo& latency_info) override {}
};

class NullIPCSender : public IPC::Sender {
 public:
  NullIPCSender() : sent_count_(0) {}
  ~NullIPCSender() override {}

  bool Send(IPC::Message* message) override {
    delete message;
    ++sent_count_;
    return true;
  }

  size_t GetAndResetSentEventCount() {
    size_t message_count = sent_count_;
    sent_count_ = 0;
    return message_count;
  }

  bool HasMessages() const { return sent_count_ > 0; }

 private:
  size_t sent_count_;
};

typedef std::vector<WebGestureEvent> Gestures;
Gestures BuildScrollSequence(size_t steps,
                             const gfx::Vector2dF& origin,
                             const gfx::Vector2dF& distance) {
  Gestures gestures;
  const gfx::Vector2dF delta = ScaleVector2d(distance, 1.f / steps);

  WebGestureEvent gesture(WebInputEvent::kGestureScrollBegin,
                          WebInputEvent::kNoModifiers,
                          ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
  gesture.x = origin.x();
  gesture.y = origin.y();
  gestures.push_back(gesture);

  gesture.SetType(WebInputEvent::kGestureScrollUpdate);
  gesture.data.scroll_update.delta_x = delta.x();
  gesture.data.scroll_update.delta_y = delta.y();
  for (size_t i = 0; i < steps; ++i) {
    gesture.x += delta.x();
    gesture.y += delta.y();
    gestures.push_back(gesture);
  }

  gesture.SetType(WebInputEvent::kGestureScrollEnd);
  gestures.push_back(gesture);
  return gestures;
}

typedef std::vector<WebTouchEvent> Touches;
Touches BuildTouchSequence(size_t steps,
                           const gfx::Vector2dF& origin,
                           const gfx::Vector2dF& distance) {
  Touches touches;
  const gfx::Vector2dF delta = ScaleVector2d(distance, 1.f / steps);

  WebTouchEvent touch(WebInputEvent::kTouchStart, WebInputEvent::kNoModifiers,
                      ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
  touch.touches_length = 1;
  touch.touches[0].id = 0;
  touch.touches[0].state = WebTouchPoint::kStatePressed;
  touch.touches[0].position.x = origin.x();
  touch.touches[0].position.y = origin.y();
  touch.touches[0].screen_position.x = origin.x();
  touch.touches[0].screen_position.y = origin.y();
  touches.push_back(touch);

  touch.SetType(WebInputEvent::kTouchMove);
  touch.touches[0].state = WebTouchPoint::kStateMoved;
  for (size_t i = 0; i < steps; ++i) {
    touch.touches[0].position.x += delta.x();
    touch.touches[0].position.y += delta.y();
    touch.touches[0].screen_position.x += delta.x();
    touch.touches[0].screen_position.y += delta.y();
    touches.push_back(touch);
  }

  touch.SetType(WebInputEvent::kTouchEnd);
  touch.touches[0].state = WebTouchPoint::kStateReleased;
  touches.push_back(touch);
  return touches;
}

class InputEventTimer {
 public:
  InputEventTimer(const char* test_name, int64_t event_count)
      : test_name_(test_name),
        event_count_(event_count),
        start_(base::TimeTicks::Now()) {}

  ~InputEventTimer() {
    perf_test::PrintResult(
        "avg_time_per_event",
        "",
        test_name_,
        static_cast<size_t>(((base::TimeTicks::Now() - start_) / event_count_)
                                .InMicroseconds()),
        "us",
        true);
  }

 private:
  const char* test_name_;
  int64_t event_count_;
  base::TimeTicks start_;
  DISALLOW_COPY_AND_ASSIGN(InputEventTimer);
};

bool ShouldBlockEventStream(const blink::WebInputEvent& event) {
  return ui::WebInputEventTraits::ShouldBlockEventStream(
      event,
      base::FeatureList::IsEnabled(features::kRafAlignedTouchInputEvents));
}

}  // namespace

class InputRouterImplPerfTest : public testing::Test {
 public:
  InputRouterImplPerfTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::UI),
        last_input_id_(0) {}
  ~InputRouterImplPerfTest() override {}

 protected:
  // testing::Test
  void SetUp() override {
    sender_.reset(new NullIPCSender());
    client_.reset(new NullInputRouterClient());
    ack_handler_.reset(new NullInputAckHandler());
    input_router_.reset(new InputRouterImpl(sender_.get(),
                                            client_.get(),
                                            ack_handler_.get(),
                                            MSG_ROUTING_NONE,
                                            InputRouterImpl::Config()));
  }

  void TearDown() override {
    base::RunLoop().RunUntilIdle();

    input_router_.reset();
    ack_handler_.reset();
    client_.reset();
    sender_.reset();
  }

  void SendEvent(const WebGestureEvent& gesture,
                 const ui::LatencyInfo& latency) {
    input_router_->SendGestureEvent(
        GestureEventWithLatencyInfo(gesture, latency));
  }

  void SendEvent(const WebTouchEvent& touch, const ui::LatencyInfo& latency) {
    input_router_->SendTouchEvent(TouchEventWithLatencyInfo(touch, latency));
  }

  void SendEventAckIfNecessary(const blink::WebInputEvent& event,
                               InputEventAckState ack_result) {
    if (!ShouldBlockEventStream(event))
      return;
    InputEventAck ack(InputEventAckSource::COMPOSITOR_THREAD, event.GetType(),
                      ack_result);
    InputHostMsg_HandleInputEvent_ACK response(0, ack);
    input_router_->OnMessageReceived(response);
  }

  void OnHasTouchEventHandlers(bool has_handlers) {
    input_router_->OnMessageReceived(
        ViewHostMsg_HasTouchEventHandlers(0, has_handlers));
  }

  size_t GetAndResetSentEventCount() {
    return sender_->GetAndResetSentEventCount();
  }

  size_t GetAndResetAckCount() { return ack_handler_->GetAndResetAckCount(); }

  size_t AckCount() const { return ack_handler_->ack_count(); }

  int64_t NextLatencyID() { return ++last_input_id_; }

  ui::LatencyInfo CreateLatencyInfo() {
    ui::LatencyInfo latency;
    latency.AddLatencyNumber(
        ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, 1, 0);
    latency.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 1,
                             NextLatencyID());
    return latency;
  }

  template <typename EventType>
  void SimulateEventSequence(const char* test_name,
                             const std::vector<EventType>& events,
                             bool ack_delay,
                             size_t iterations) {
    OnHasTouchEventHandlers(true);

    const size_t event_count = events.size();
    const size_t total_event_count = event_count * iterations;

    InputEventTimer timer(test_name, total_event_count);
    while (iterations--) {
      size_t i = 0, ack_i = 0;
      if (ack_delay)
        SendEvent(events[i++], CreateLatencyInfo());

      for (; i < event_count; ++i, ++ack_i) {
        SendEvent(events[i], CreateLatencyInfo());
        SendEventAckIfNecessary(events[ack_i], INPUT_EVENT_ACK_STATE_CONSUMED);
      }

      if (ack_delay)
        SendEventAckIfNecessary(events.back(), INPUT_EVENT_ACK_STATE_CONSUMED);

      EXPECT_EQ(event_count, GetAndResetSentEventCount());
      EXPECT_EQ(event_count, GetAndResetAckCount());
    }
  }

  void SimulateTouchAndScrollEventSequence(const char* test_name,
                                           size_t steps,
                                           const gfx::Vector2dF& origin,
                                           const gfx::Vector2dF& distance,
                                           size_t iterations) {
    OnHasTouchEventHandlers(true);

    Gestures gestures = BuildScrollSequence(steps, origin, distance);
    Touches touches = BuildTouchSequence(steps, origin, distance);
    ASSERT_EQ(touches.size(), gestures.size());

    const size_t event_count = gestures.size();
    const size_t total_event_count = event_count * iterations * 2;

    InputEventTimer timer(test_name, total_event_count);
    while (iterations--) {
      for (size_t i = 0; i < event_count; ++i) {
        SendEvent(touches[i], CreateLatencyInfo());
        // Touches may not be forwarded after the scroll sequence has begun, so
        // only ack if necessary.
        if (!AckCount()) {
          SendEventAckIfNecessary(touches[i],
                                  INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
        }

        SendEvent(gestures[i], CreateLatencyInfo());
        SendEventAckIfNecessary(gestures[i], INPUT_EVENT_ACK_STATE_CONSUMED);
        EXPECT_EQ(2U, GetAndResetAckCount());
      }
    }
  }

 private:
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  int64_t last_input_id_;
  std::unique_ptr<NullIPCSender> sender_;
  std::unique_ptr<NullInputRouterClient> client_;
  std::unique_ptr<NullInputAckHandler> ack_handler_;
  std::unique_ptr<InputRouterImpl> input_router_;
};

const size_t kDefaultSteps(100);
const size_t kDefaultIterations(100);
const gfx::Vector2dF kDefaultOrigin(100, 100);
const gfx::Vector2dF kDefaultDistance(500, 500);

TEST_F(InputRouterImplPerfTest, TouchSwipe) {
  SimulateEventSequence(
      "TouchSwipe ",
      BuildTouchSequence(kDefaultSteps, kDefaultOrigin, kDefaultDistance),
      false,
      kDefaultIterations);
}

TEST_F(InputRouterImplPerfTest, TouchSwipeDelayedAck) {
  SimulateEventSequence(
      "TouchSwipeDelayedAck ",
      BuildTouchSequence(kDefaultSteps, kDefaultOrigin, kDefaultDistance),
      true,
      kDefaultIterations);
}

TEST_F(InputRouterImplPerfTest, GestureScroll) {
  SimulateEventSequence(
      "GestureScroll ",
      BuildScrollSequence(kDefaultSteps, kDefaultOrigin, kDefaultDistance),
      false,
      kDefaultIterations);
}

TEST_F(InputRouterImplPerfTest, GestureScrollDelayedAck) {
  SimulateEventSequence(
      "GestureScrollDelayedAck ",
      BuildScrollSequence(kDefaultSteps, kDefaultOrigin, kDefaultDistance),
      true,
      kDefaultIterations);
}

TEST_F(InputRouterImplPerfTest, TouchSwipeToGestureScroll) {
  SimulateTouchAndScrollEventSequence("TouchSwipeToGestureScroll ",
                                      kDefaultSteps,
                                      kDefaultOrigin,
                                      kDefaultDistance,
                                      kDefaultIterations);
}

}  // namespace content
