// 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.

#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_INPUT_HANDLER_H_
#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_INPUT_HANDLER_H_

#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/raw_ref.h"
#include "base/memory/weak_ptr.h"
#include "content/browser/devtools/protocol/devtools_domain_handler.h"
#include "content/browser/devtools/protocol/input.h"
#include "content/browser/renderer_host/render_widget_host_view_base.h"
#include "content/common/input/synthetic_gesture.h"
#include "content/common/input/synthetic_pointer_action_list_params.h"
#include "content/common/input/synthetic_smooth_scroll_gesture_params.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/web_contents.h"
#include "third_party/blink/public/common/input/pointer_id.h"
#include "third_party/blink/public/common/input/web_input_event.h"
#include "third_party/blink/public/common/input/web_mouse_event.h"
#include "third_party/blink/public/mojom/page/widget.mojom.h"

namespace content {
class DevToolsAgentHostImpl;
class RenderFrameHostImpl;
class RenderWidgetHostImpl;
class SyntheticPointerDriver;
class WebContentsImpl;

namespace protocol {

template <class BackendCallback>
class FailSafe;

class InputHandler : public DevToolsDomainHandler, public Input::Backend {
 public:
  InputHandler(bool allow_file_access, bool allow_sending_input_to_browser);

  InputHandler(const InputHandler&) = delete;
  InputHandler& operator=(const InputHandler&) = delete;

  ~InputHandler() override;

  static std::vector<InputHandler*> ForAgentHost(DevToolsAgentHostImpl* host);

  void Wire(UberDispatcher* dispatcher) override;
  void SetRenderer(int process_host_id,
                   RenderFrameHostImpl* frame_host) override;

  // StartDragging is used to inform CDP's InputHandler to start dragging. This
  // gets called whenever the renderer tells the content layer to initiate
  // dragging (see RenderWidgetHostImpl::StartDragging)
  void StartDragging(const DropData& drop_data,
                     const blink::mojom::DragData& drag_data,
                     blink::DragOperationsMask drag_operations_mask,
                     bool* intercepted);
  // DragEnded is used to inform CDP's InputHandler when a drag has ended. This
  // gets called whenever the Drag n' Drop APIs that end dragging get called
  // (all of which exist in RenderWidgetHostImpl).
  //
  // This function ensures the drag state of Chromium is in-sync no matter the
  // source of the drag end.
  //
  // In theory, if OS drag gets initiated, then this function gets called when
  // the OS drag ends. This can happen if some starts and ends a drag with the
  // OS manually before starting to use CDP. In practice, this doesn't occur.
  void DragEnded();

  Response Disable() override;

  void DispatchKeyEvent(
      const std::string& type,
      std::optional<int> modifiers,
      std::optional<double> timestamp,
      std::optional<std::string> text,
      std::optional<std::string> unmodified_text,
      std::optional<std::string> key_identifier,
      std::optional<std::string> code,
      std::optional<std::string> key,
      std::optional<int> windows_virtual_key_code,
      std::optional<int> native_virtual_key_code,
      std::optional<bool> auto_repeat,
      std::optional<bool> is_keypad,
      std::optional<bool> is_system_key,
      std::optional<int> location,
      std::unique_ptr<Array<std::string>> commands,
      std::unique_ptr<DispatchKeyEventCallback> callback) override;

  void InsertText(const std::string& text,
                  std::unique_ptr<InsertTextCallback> callback) override;

  void ImeSetComposition(
      const std::string& text,
      int selection_start,
      int selection_end,
      std::optional<int> replacement_start,
      std::optional<int> replacement_end,
      std::unique_ptr<ImeSetCompositionCallback> callback) override;

  void DispatchMouseEvent(
      const std::string& event_type,
      double x,
      double y,
      std::optional<int> modifiers,
      std::optional<double> timestamp,
      std::optional<std::string> button,
      std::optional<int> buttons,
      std::optional<int> click_count,
      std::optional<double> force,
      std::optional<double> tangential_pressure,
      std::optional<double> tilt_x,
      std::optional<double> tilt_y,
      std::optional<int> twist,
      std::optional<double> delta_x,
      std::optional<double> delta_y,
      std::optional<std::string> pointer_type,
      std::unique_ptr<DispatchMouseEventCallback> callback) override;

  void DispatchDragEvent(
      const std::string& event_type,
      double x,
      double y,
      std::unique_ptr<Input::DragData> data,
      std::optional<int> modifiers,
      std::unique_ptr<DispatchDragEventCallback> callback) override;

  void DispatchTouchEvent(
      const std::string& type,
      std::unique_ptr<Array<Input::TouchPoint>> touch_points,
      std::optional<int> modifiers,
      std::optional<double> timestamp,
      std::unique_ptr<DispatchTouchEventCallback> callback) override;

  void CancelDragging(
      std::unique_ptr<CancelDraggingCallback> callback) override;

  Response EmulateTouchFromMouseEvent(const std::string& type,
                                      int x,
                                      int y,
                                      const std::string& button,
                                      std::optional<double> timestamp,
                                      std::optional<double> delta_x,
                                      std::optional<double> delta_y,
                                      std::optional<int> modifiers,
                                      std::optional<int> click_count) override;

  Response SetIgnoreInputEvents(bool ignore) override;
  Response SetInterceptDrags(bool enabled) override;

  void SynthesizePinchGesture(
      double x,
      double y,
      double scale_factor,
      std::optional<int> relative_speed,
      std::optional<std::string> gesture_source_type,
      std::unique_ptr<SynthesizePinchGestureCallback> callback) override;

  void SynthesizeScrollGesture(
      double x,
      double y,
      std::optional<double> x_distance,
      std::optional<double> y_distance,
      std::optional<double> x_overscroll,
      std::optional<double> y_overscroll,
      std::optional<bool> prevent_fling,
      std::optional<int> speed,
      std::optional<std::string> gesture_source_type,
      std::optional<int> repeat_count,
      std::optional<int> repeat_delay_ms,
      std::optional<std::string> interaction_marker_name,
      std::unique_ptr<SynthesizeScrollGestureCallback> callback) override;

  void SynthesizeTapGesture(
      double x,
      double y,
      std::optional<int> duration,
      std::optional<int> tap_count,
      std::optional<std::string> gesture_source_type,
      std::unique_ptr<SynthesizeTapGestureCallback> callback) override;

 private:
  class InputInjector;
  class DragController {
   public:
    // `handler` must live as long as the drag controller.
    explicit DragController(InputHandler& handler);
    ~DragController();

    DragController(const DragController&) = delete;
    DragController& operator=(const DragController&) = delete;

    // Returns `true` if the drag controller handles the mouse event. All
    // arguments will be moved in this case.
    bool HandleMouseEvent(
        RenderWidgetHostImpl& host,
        const blink::WebMouseEvent& event,
        std::unique_ptr<DispatchMouseEventCallback>& callback);

    // You should call this whenever dragging needs to be cancelled (perhaps an
    // invalid state or desired by the user).
    void CancelDragging(base::OnceClosure callback);

    // Returns `true` if we are currently dragging.
    bool IsDragging() { return !!drag_state_; }

   private:
    struct DragState;
    struct InitialState;

    friend void InputHandler::StartDragging(
        const DropData& drop_data,
        const blink::mojom::DragData& drag_data,
        blink::DragOperationsMask drag_operations_mask,
        bool* intercepted);
    friend void InputHandler::DragEnded();

    void EnsureDraggingEntered(RenderWidgetHostImpl& host,
                               const blink::WebMouseEvent& event);

    // Called by the input handler to start a dragging session.
    void StartDragging(const content::DropData& drop_data,
                       blink::DragOperationsMask drag_operations_mask);

    // Updates the drag with the given mouse event.
    //
    // `callback` may be null.
    void UpdateDragging(
        RenderWidgetHostImpl& host,
        std::unique_ptr<blink::WebMouseEvent> event,
        std::unique_ptr<FailSafe<DispatchMouseEventCallback>> callback);
    void DragUpdated(
        std::unique_ptr<blink::WebMouseEvent> event,
        std::unique_ptr<FailSafe<DispatchMouseEventCallback>> callback,
        ui::mojom::DragOperation operation,
        bool document_is_handling_drag);

    // Ends the drag with the given event and host.
    //
    // Note only the modifiers for the event are really used here, so it's
    // expected you've updated the drag with the latest info (e.g. position)
    // excluding modifiers. This ensures the drag event sequence is semantically
    // correct. The event itself is still needed in case dragging suddenly stops
    // for external reasons and we need to reschedule it.
    //
    // Also note the host is only used if there are no updates ongoing.
    // Otherwise, it's a nullptr. This is an optimization.
    void EndDragging(
        RenderWidgetHostImpl* host,
        std::unique_ptr<blink::WebMouseEvent> event,
        std::unique_ptr<FailSafe<DispatchMouseEventCallback>> callback);
    void EndDraggingWithRenderWidgetHostAtPoint(
        std::unique_ptr<blink::WebMouseEvent> event,
        std::unique_ptr<FailSafe<DispatchMouseEventCallback>> callback,
        base::WeakPtr<RenderWidgetHostViewBase> view,
        std::optional<gfx::PointF> maybe_point);

    const raw_ref<InputHandler> handler_;

    // These get used for starting a drag.
    std::unique_ptr<InitialState> initial_state_;

    std::unique_ptr<DragState> drag_state_;

    base::WeakPtrFactory<DragController> weak_factory_{this};
  };

  void DispatchWebTouchEvent(
      const std::string& type,
      std::unique_ptr<Array<Input::TouchPoint>> touch_points,
      std::optional<int> modifiers,
      std::optional<double> timestamp,
      std::unique_ptr<DispatchTouchEventCallback> callback);

  void DispatchSyntheticPointerActionTouch(
      const std::string& type,
      std::unique_ptr<Array<Input::TouchPoint>> touch_points,
      std::optional<int> modifiers,
      std::optional<double> timestamp,
      std::unique_ptr<DispatchTouchEventCallback> callback);

  void OnWidgetForDispatchMouseEvent(
      std::unique_ptr<DispatchMouseEventCallback> callback,
      std::unique_ptr<blink::WebMouseEvent> mouse_event,
      base::WeakPtr<RenderWidgetHostViewBase> target,
      std::optional<gfx::PointF> point);

  void OnWidgetForDispatchDragEvent(
      const std::string& event_type,
      double x,
      double y,
      std::unique_ptr<Input::DragData> data,
      std::optional<int> modifiers,
      std::unique_ptr<DispatchDragEventCallback> callback,
      base::WeakPtr<RenderWidgetHostViewBase> target,
      std::optional<gfx::PointF> point);

  void OnWidgetForDispatchWebTouchEvent(
      std::unique_ptr<DispatchTouchEventCallback> callback,
      std::vector<blink::WebTouchEvent> events,
      base::WeakPtr<RenderWidgetHostViewBase> target,
      std::optional<gfx::PointF> point);

  SyntheticPointerActionParams PrepareSyntheticPointerActionParams(
      SyntheticPointerActionParams::PointerActionType pointer_action_type,
      int id,
      double x,
      double y,
      int key_modifiers,
      float radius_x = 1.f,
      float radius_y = 1.f,
      float rotation_angle = 0.f,
      float force = 1.f);

  void SynthesizeRepeatingScroll(
      SyntheticSmoothScrollGestureParams gesture_params,
      int repeat_count,
      base::TimeDelta repeat_delay,
      std::string interaction_marker_name,
      int id,
      std::unique_ptr<SynthesizeScrollGestureCallback> callback);

  void OnScrollFinished(
      SyntheticSmoothScrollGestureParams gesture_params,
      int repeat_count,
      base::TimeDelta repeat_delay,
      std::string interaction_marker_name,
      int id,
      std::unique_ptr<SynthesizeScrollGestureCallback> callback,
      SyntheticGesture::Result result);

  void HandleMouseEvent(std::unique_ptr<blink::WebMouseEvent> event,
                        std::unique_ptr<DispatchMouseEventCallback> callback);

  void ClearInputState();
  bool PointIsWithinContents(gfx::PointF point) const;
  InputInjector* EnsureInjector(RenderWidgetHostImpl* widget_host);

  RenderWidgetHostViewBase* GetRootView();

  float ScaleFactor();

  raw_ptr<RenderFrameHostImpl> host_ = nullptr;
  // WebContents associated with the |host_|.
  raw_ptr<WebContentsImpl> web_contents_ = nullptr;
  std::unique_ptr<Input::Frontend> frontend_;
  base::flat_set<std::unique_ptr<InputInjector>, base::UniquePtrComparator>
      injectors_;
  int last_id_ = 0;
  bool ignore_input_events_ = false;
  std::optional<content::WebContents::ScopedIgnoreInputEvents>
      scoped_ignore_input_events_;
  bool intercept_drags_ = false;
  DragController drag_controller_;
  const bool allow_file_access_;
  const bool allow_sending_input_to_browser_ = false;
  std::set<int> pointer_ids_;
  std::unique_ptr<SyntheticPointerDriver> synthetic_pointer_driver_;
  base::flat_map<blink::PointerId, blink::WebTouchPoint> touch_points_;
  base::WeakPtrFactory<InputHandler> weak_factory_{this};
};

}  // namespace protocol
}  // namespace content

#endif  // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_INPUT_HANDLER_H_
