// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/input/gesture_event_queue.h"

#include "base/auto_reset.h"
#include "base/trace_event/trace_event.h"
#include "components/input/touchpad_tap_suppression_controller.h"
#include "components/input/touchscreen_tap_suppression_controller.h"
#include "ui/events/blink/blink_features.h"
#include "ui/events/blink/web_input_event_traits.h"

using blink::WebGestureEvent;
using blink::WebInputEvent;

namespace input {

GestureEventQueue::GestureEventWithLatencyInfoAckState::
    GestureEventWithLatencyInfoAckState(
        const GestureEventWithLatencyInfo& event)
    : GestureEventWithLatencyInfo(event) {}

GestureEventWithLatencyInfoAndCallback::GestureEventWithLatencyInfoAndCallback(
    const GestureEventWithLatencyInfo& event,
    DispatchToRendererCallback callback)
    : GestureEventWithLatencyInfo(event),
      dispatch_callback(std::move(callback)) {}

GestureEventWithLatencyInfoAndCallback::GestureEventWithLatencyInfoAndCallback(
    GestureEventWithLatencyInfoAndCallback&& event)
    : GestureEventWithLatencyInfo(event.event, event.latency),
      dispatch_callback(std::move(event.dispatch_callback)) {}

GestureEventWithLatencyInfoAndCallback::
    ~GestureEventWithLatencyInfoAndCallback() = default;

GestureEventQueue::Config::Config() = default;

GestureEventQueue::GestureEventQueue(
    GestureEventQueueClient* client,
    FlingControllerEventSenderClient* fling_event_sender_client,
    FlingControllerSchedulerClient* fling_scheduler_client,
    const Config& config)
    : client_(client),
      scrolling_in_progress_(false),
      debounce_interval_(config.debounce_interval),
      fling_controller_(fling_event_sender_client,
                        fling_scheduler_client,
                        config.fling_config) {
  DCHECK(client);
  DCHECK(fling_event_sender_client);
  DCHECK(fling_scheduler_client);
}

GestureEventQueue::~GestureEventQueue() = default;

bool GestureEventQueue::DebounceOrForwardEvent(
    const GestureEventWithLatencyInfo& gesture_event,
    DispatchToRendererCallback& dispatch_callback) {
  // GFS and GFC should have been filtered in PassToFlingController.
  DCHECK_NE(gesture_event.event.GetType(),
            WebInputEvent::Type::kGestureFlingStart);
  DCHECK_NE(gesture_event.event.GetType(),
            WebInputEvent::Type::kGestureFlingCancel);
  if (!ShouldForwardForBounceReduction(gesture_event, dispatch_callback)) {
    return false;
  }

  ForwardGestureEvent(gesture_event, dispatch_callback);
  return true;
}

bool GestureEventQueue::PassToFlingController(
    const GestureEventWithLatencyInfo& gesture_event) {
  return fling_controller_.ObserveAndMaybeConsumeGestureEvent(gesture_event);
}

void GestureEventQueue::QueueDeferredEvents(
    const GestureEventWithLatencyInfo& gesture_event,
    DispatchToRendererCallback& dispatch_callback) {
  deferred_gesture_queue_.emplace_back(gesture_event,
                                       std::move(dispatch_callback));
}

GestureEventQueue::GestureWithCallbackQueue
GestureEventQueue::TakeDeferredEvents() {
  GestureWithCallbackQueue deferred_gesture_events;
  deferred_gesture_events.swap(deferred_gesture_queue_);
  return deferred_gesture_events;
}

void GestureEventQueue::StopFling() {
  fling_controller_.StopFling();
}

gfx::Vector2dF GestureEventQueue::CurrentFlingVelocity() const {
  return fling_controller_.CurrentFlingVelocity();
}

bool GestureEventQueue::FlingInProgressForTest() const {
  return fling_controller_.fling_in_progress();
}

bool GestureEventQueue::ShouldForwardForBounceReduction(
    const GestureEventWithLatencyInfo& gesture_event,
    DispatchToRendererCallback& dispatch_callback) {
  if (debounce_interval_ <= base::TimeDelta()) {
    return true;
  }

  WebInputEvent::Type event_type = gesture_event.event.GetType();
  if (event_type == WebInputEvent::Type::kGestureScrollEnd) {
    // We no longer care about the previous GestureScrollEnd.
    // Note: this needs to be reset before the fling_in_progress() exit.
    scroll_end_filtered_by_deboucing_deferral_queue_ = false;
  }

  // Don't debounce any gesture events while a fling is in progress on the
  // browser side. A GSE event in this case ends fling progress and it shouldn't
  // get cancelled by its next GSB event.
  if (fling_controller_.fling_in_progress()) {
    return true;
  }

  switch (event_type) {
    case WebInputEvent::Type::kGestureScrollUpdate:
      // This will restart the timer if it is already running.
      debounce_deferring_timer_.Start(
          FROM_HERE, debounce_interval_, this,
          &GestureEventQueue::SendScrollEndingEventsNow);
      scrolling_in_progress_ = true;
      debouncing_deferral_queue_.clear();
      return true;

    case WebInputEvent::Type::kGesturePinchBegin:
    case WebInputEvent::Type::kGesturePinchEnd:
    case WebInputEvent::Type::kGesturePinchUpdate:
      return true;
    case WebInputEvent::Type::kGestureScrollBegin:
      // GSB event should not get filtered by the debouncing_deferral_queue_
      // when its previous GSE event is forwarded to the renderer.
      if (!scroll_end_filtered_by_deboucing_deferral_queue_) {
        return true;
      } else {
        debouncing_deferral_queue_.emplace_back(gesture_event,
                                                std::move(dispatch_callback));
        return false;
      }
    case WebInputEvent::Type::kGestureScrollEnd:
      // GSEs generated by the fling controller should not get pushed to the
      // debouncing_deferral_queue_.
      if (gesture_event.event.data.scroll_end.generated_by_fling_controller) {
        scrolling_in_progress_ = false;
        return true;
      }
      if (scrolling_in_progress_) {
        debouncing_deferral_queue_.emplace_back(gesture_event,
                                                std::move(dispatch_callback));
        scroll_end_filtered_by_deboucing_deferral_queue_ = true;
        return false;
      }
      return true;
    default:
      if (scrolling_in_progress_) {
        debouncing_deferral_queue_.emplace_back(gesture_event,
                                                std::move(dispatch_callback));
        return false;
      }
      return true;
  }
}

void GestureEventQueue::ForwardGestureEvent(
    const GestureEventWithLatencyInfo& gesture_event,
    DispatchToRendererCallback& dispatch_callback) {
  // GFS and GFC should have been filtered in PassToFlingController to get
  // handled by fling controller.
  DCHECK_NE(gesture_event.event.GetType(),
            WebInputEvent::Type::kGestureFlingStart);
  DCHECK_NE(gesture_event.event.GetType(),
            WebInputEvent::Type::kGestureFlingCancel);
  sent_events_awaiting_ack_.push_back(gesture_event);
  client_->SendGestureEventImmediately(gesture_event, dispatch_callback);
  // `ForwardGestureEvent` could be called on enqueued events as well, DCHECK
  // ensures the corresponding callback was run.
  CHECK(!dispatch_callback);
}

void GestureEventQueue::ProcessGestureAck(
    blink::mojom::InputEventResultSource ack_source,
    blink::mojom::InputEventResultState ack_result,
    WebInputEvent::Type type,
    const ui::LatencyInfo& latency) {
  TRACE_EVENT0("input", "GestureEventQueue::ProcessGestureAck");

  if (sent_events_awaiting_ack_.empty()) {
    DLOG(ERROR) << "Received unexpected ACK for event type " << type;
    return;
  }

  // ACKs could come back out of order. We want to cache them to restore the
  // original order.
  for (auto& outstanding_event : sent_events_awaiting_ack_) {
    if (outstanding_event.ack_state() !=
        blink::mojom::InputEventResultState::kUnknown) {
      continue;
    }
    if (outstanding_event.event.GetType() == type) {
      outstanding_event.latency.AddNewLatencyFrom(latency);
      outstanding_event.set_ack_info(ack_source, ack_result);
      break;
    }
  }

  AckCompletedEvents();
}

void GestureEventQueue::AckCompletedEvents() {
  // Don't allow re-entrancy into this method otherwise
  // the ordering of acks won't be preserved.
  if (processing_acks_) {
    return;
  }
  base::AutoReset<bool> process_acks(&processing_acks_, true);
  while (!sent_events_awaiting_ack_.empty()) {
    auto iter = sent_events_awaiting_ack_.begin();
    if (iter->ack_state() == blink::mojom::InputEventResultState::kUnknown) {
      break;
    }
    GestureEventWithLatencyInfoAckState event = *iter;
    sent_events_awaiting_ack_.erase(iter);

    AckGestureEventToClient(event, event.ack_source(), event.ack_state());
  }
}

void GestureEventQueue::AckGestureEventToClient(
    const GestureEventWithLatencyInfo& event_with_latency,
    blink::mojom::InputEventResultSource ack_source,
    blink::mojom::InputEventResultState ack_result) {
  client_->OnGestureEventAck(event_with_latency, ack_source, ack_result);
}

TouchpadTapSuppressionController*
GestureEventQueue::GetTouchpadTapSuppressionController() {
  return fling_controller_.GetTouchpadTapSuppressionController();
}

void GestureEventQueue::SendScrollEndingEventsNow() {
  scrolling_in_progress_ = false;
  if (debouncing_deferral_queue_.empty()) {
    return;
  }
  GestureWithCallbackQueue debouncing_deferral_queue;
  debouncing_deferral_queue.swap(debouncing_deferral_queue_);
  for (auto& gesture_with_callback : debouncing_deferral_queue) {
    if (!fling_controller_.ObserveAndMaybeConsumeGestureEvent(
            gesture_with_callback)) {
      if (gesture_with_callback.event.GetType() ==
          WebInputEvent::Type::kGestureScrollEnd) {
        scroll_end_filtered_by_deboucing_deferral_queue_ = false;
      }
      ForwardGestureEvent(gesture_with_callback,
                          gesture_with_callback.dispatch_callback);
    } else {
      std::move(gesture_with_callback.dispatch_callback)
          .Run(gesture_with_callback.event,
               DispatchToRendererResult::kNotDispatched);
    }
  }
}

void GestureEventQueue::OnWheelEventAck(
    const MouseWheelEventWithLatencyInfo& event,
    blink::mojom::InputEventResultSource ack_source,
    blink::mojom::InputEventResultState ack_result) {
  fling_controller_.OnWheelEventAck(event, ack_source, ack_result);
}

}  // namespace input
