// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// Text editing functionality delegated from |PlatformView|.
/// See |TextDelegate| for details.

#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_TEXT_DELEGATE_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_TEXT_DELEGATE_H_

#include <memory>

#include <fuchsia/ui/input/cpp/fidl.h>
#include <fuchsia/ui/input3/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>

#include "flutter/lib/ui/window/platform_message.h"
#include "flutter/shell/common/platform_view.h"
#include "flutter/shell/platform/fuchsia/flutter/keyboard.h"

#include "logging.h"

namespace flutter_runner {

/// The channel name used for text editing platofrm messages.
constexpr char kTextInputChannel[] = "flutter/textinput";

/// The channel name used for key event platform messages.
constexpr char kKeyEventChannel[] = "flutter/keyevent";

/// TextDelegate handles keyboard inpout and text editing.
///
/// It mediates between Fuchsia's input and Flutter's platform messages. When it
/// is initialized, it contacts `fuchsia.ui.input.Keyboard` to register itself
/// as listener of key events.
///
/// Whenever a text editing request comes from the
/// Flutter app, it will activate Fuchsia's input method editor, and will send
/// text edit actions coming from the Fuchsia platform over to the Flutter app,
/// by converting FIDL messages (`fuchsia.ui.input.InputMethodEditorClient`
/// calls) to appropriate text editing Flutter platform messages.
///
/// For details refer to:
///   * Flutter side:
///   https://api.flutter.dev/javadoc/io/flutter/embedding/engine/systemchannels/TextInputChannel.html
///   * Fuchsia side: https://fuchsia.dev/reference/fidl/fuchsia.ui.input
class TextDelegate : public fuchsia::ui::input3::KeyboardListener,
                     public fuchsia::ui::input::InputMethodEditorClient {
 public:
  /// Creates a new TextDelegate.
  ///
  /// Args:
  ///   view_ref: the reference to the app's view. Required for registration
  ///     with Fuchsia.
  ///   ime_service: a handle to Fuchsia's input method service.
  ///   keyboard: the keyboard listener, gets notified of key presses and
  ///     releases.
  ///   dispatch_callback: a function used to send a Flutter platform message.
  TextDelegate(fuchsia::ui::views::ViewRef view_ref,
               fuchsia::ui::input::ImeServiceHandle ime_service,
               fuchsia::ui::input3::KeyboardHandle keyboard,
               std::function<void(std::unique_ptr<flutter::PlatformMessage>)>
                   dispatch_callback);

  /// |fuchsia.ui.input3.KeyboardListener|
  /// Called by the embedder every time there is a key event to process.
  void OnKeyEvent(fuchsia::ui::input3::KeyEvent key_event,
                  fuchsia::ui::input3::KeyboardListener::OnKeyEventCallback
                      callback) override;

  /// |fuchsia::ui::input::InputMethodEditorClient|
  /// Called by the embedder every time the edit state is updated.
  void DidUpdateState(
      fuchsia::ui::input::TextInputState state,
      std::unique_ptr<fuchsia::ui::input::InputEvent> event) override;

  /// |fuchsia::ui::input::InputMethodEditorClient|
  /// Called by the embedder when the action key is pressed, and the requested
  /// action is supplied to Flutter.
  void OnAction(fuchsia::ui::input::InputMethodAction action) override;

  /// Gets a new input method editor from the input connection. Run when both
  /// Scenic has focus and Flutter has requested input with setClient.
  void ActivateIme();

  /// Detaches the input method editor connection, ending the edit session and
  /// closing the onscreen keyboard. Call when input is no longer desired,
  /// either because Scenic says we lost focus or when Flutter no longer has a
  /// text field focused.
  void DeactivateIme();

  /// Channel handler for kTextInputChannel
  bool HandleFlutterTextInputChannelPlatformMessage(
      std::unique_ptr<flutter::PlatformMessage> message);

  /// Returns true if there is a text state (i.e. if some text editing is in
  /// progress).
  bool HasTextState() { return last_text_state_.has_value(); }

 private:
  // Activates the input method editor, assigning |action| to the "enter" key.
  // This action will be reported by |OnAction| above when the "enter" key is
  // pressed. Note that in the case of multi-line text editors, |OnAction| will
  // never be called: instead, the text editor will insert a newline into the
  // edited text.
  void ActivateIme(fuchsia::ui::input::InputMethodAction action);

  // Converts Fuchsia platform key codes into Flutter key codes.
  Keyboard keyboard_translator_;

  // A callback for sending a single Flutter platform message.
  std::function<void(std::unique_ptr<flutter::PlatformMessage>)>
      dispatch_callback_;

  // TextDelegate server-side binding.  Methods called when the text edit state
  // is updated.
  fidl::Binding<fuchsia::ui::input::InputMethodEditorClient> ime_client_;

  // An interface for interacting with a text input control.
  fuchsia::ui::input::InputMethodEditorPtr ime_;

  // An interface for requesting the InputMethodEditor.
  fuchsia::ui::input::ImeServicePtr text_sync_service_;

  // The locally-unique identifier of the text input currently in use. Flutter
  // usually uses only one at a time.
  int current_text_input_client_ = 0;

  // TextDelegate server side binding. Methods called when a key is pressed.
  fidl::Binding<fuchsia::ui::input3::KeyboardListener>
      keyboard_listener_binding_;

  // The client-side stub for calling the Keyboard protocol.
  fuchsia::ui::input3::KeyboardPtr keyboard_;

  // last_text_state_ is the last state of the text input as reported by the IME
  // or initialized by Flutter. We set it to null if Flutter doesn't want any
  // input, since then there is no text input state at all.
  // If nullptr, then no editing is in progress.
  std::optional<fuchsia::ui::input::TextInputState> last_text_state_;

  // The action that Flutter expects to happen when the user presses the "enter"
  // key.  For example, it could be `InputMethodAction::DONE` which would cause
  // text editing to stop and the current text to be accepted.
  // If set to std::nullopt, then no editing is in progress.
  std::optional<fuchsia::ui::input::InputMethodAction> requested_text_action_;

  FML_DISALLOW_COPY_AND_ASSIGN(TextDelegate);
};

}  // namespace flutter_runner

#endif  // FLUTTER_SHELL_PLATFORM_FUCHSIA_TEXT_DELEGATE_H_
