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

#ifndef SRC_ACCESSIBILITY_BRIDGE_H_
#define SRC_ACCESSIBILITY_BRIDGE_H_

#include <fuchsia/accessibility/semantics/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/sys/inspect/cpp/component.h>
#include <zircon/types.h>

#include <memory>
#include <optional>
#include <queue>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "src/embedder/engine/embedder.h"

namespace embedder {

/// Accessibility bridge.
///
/// This class intermediates accessibility-related calls between Fuchsia and
/// Flutter, translating and relaying requests between Flutter's
/// platform-agnostic accessibility APIs and Fuchsia's APIs and behaviour.
///
/// This bridge performs the following functions, among others:
///
/// * Translates Flutter's semantics node updates to events Fuchsia requires
///   (e.g. Flutter only sends updates for changed nodes, but Fuchsia requires
///   the entire flattened subtree to be sent when a node changes.
class AccessibilityBridge : public fuchsia::accessibility::semantics::SemanticListener {
 public:
  using SetSemanticsEnabledCallback = std::function<void(bool)>;
  using DispatchSemanticsActionCallback = std::function<void(int32_t, FlutterSemanticsAction)>;

  // TODO(MI4-2531, FIDL-718): Remove this. We shouldn't be worried about
  // batching messages at this level.
  // FIDL may encode a C++ struct as larger than the sizeof the C++ struct.
  // This is to make sure we don't send updates that are too large.
  static constexpr uint32_t kMaxMessageSize = ZX_CHANNEL_MAX_MSG_BYTES / 2;

  static_assert(fuchsia::accessibility::semantics::MAX_LABEL_SIZE < kMaxMessageSize - 1);

  /// Flutter uses signed 32 bit integers for node IDs, while Fuchsia uses
  /// unsigned 32 bit integers. A change in the size on either one would break
  /// casts and size tracking logic in the implementation.
  static constexpr size_t kNodeIdSize = sizeof(FlutterSemanticsNode::id);
  static_assert(kNodeIdSize == sizeof(fuchsia::accessibility::semantics::Node().node_id()),
                "FlutterSemanticsNode::id and "
                "fuchsia::accessibility::semantics::Node::node_id differ in size.");

  /// Maximum number of node ids to be deleted through the Semantics API.
  static constexpr size_t kMaxDeletionsPerUpdate = kMaxMessageSize / kNodeIdSize;

  /// set_semantics_enabled_callback is the callback to be run following an
  /// invocation of the OnSemanticsModeChanged FIDL interface from Fuchsia.
  ///
  /// dispatch_semantics_action_callback is the callback to be run following an
  /// invocation of the OnAccessibilityActionRequested FIDL interface from Fuchsia.
  ///
  /// semantics_manager is the Fuchsia semantics manager component
  ///
  /// view_ref is the accessibility view reference initialized in main.cc
  ///
  /// inspect_node is a child node of Fuchsia's ComponentInspector
  AccessibilityBridge(SetSemanticsEnabledCallback set_semantics_enabled_callback,
                      DispatchSemanticsActionCallback dispatch_semantics_action_callback,
                      fuchsia::accessibility::semantics::SemanticsManagerHandle semantics_manager,
                      fuchsia::ui::views::ViewRef view_ref, inspect::Node inspect_node);

  /// Disable Copy and Assignment
  AccessibilityBridge(const AccessibilityBridge&) = delete;
  AccessibilityBridge& operator=(const AccessibilityBridge&) = delete;

  /// Returns true if accessible navigation is enabled.
  bool GetSemanticsEnabled() const;

  /// Enables Flutter accessibility navigation features.
  ///
  /// Once enabled, any semantics updates in the Flutter application will
  /// trigger |FuchsiaAccessibility::DispatchAccessibilityEvent| callbacks
  /// to send events back to the Fuchsia SemanticsManager.
  void SetSemanticsEnabled(bool enabled);

  /// Handle FlutterSemanticsNode from embedder API
  void AddSemanticsUpdate(const FlutterSemanticsUpdate* update);

  /// Handle platform message from the flutter engine
  void HandlePlatformMessage(const FlutterPlatformMessage* message);

  /// Requests a message announcement from the accessibility TTS system.
  void RequestAnnounce(const std::string message);

  /// Notifies the bridge of a 'hover move' touch exploration event.
  zx_status_t OnHoverMove(double x, double y);

  /// |fuchsia::accessibility::semantics::SemanticListener|
  void HitTest(
      fuchsia::math::PointF local_point,
      fuchsia::accessibility::semantics::SemanticListener::HitTestCallback callback) override;

  /// |fuchsia::accessibility::semantics::SemanticListener|
  void OnAccessibilityActionRequested(
      uint32_t node_id, fuchsia::accessibility::semantics::Action action,
      fuchsia::accessibility::semantics::SemanticListener::OnAccessibilityActionRequestedCallback
          callback) override;

  /// Set the internal pixel ratio
  ///
  /// This is the factor used to convert between a view’s logical
  /// coordinate space (assigned by scenic) and its allocated buffer size
  void SetPixelRatio(float ratio);

 private:
  /// Fuchsia's default root semantic node id.
  static constexpr int32_t kRootNodeId = 0;

  /// Represents an atomic semantic update to Fuchsia, which can contain deletes
  /// and updates of semantic nodes.
  ///
  /// An atomic update is a set of operations that take a semantic tree in a
  /// valid state to another valid state. Please check the semantics FIDL
  /// documentation for details.
  struct FuchsiaAtomicUpdate {
    FuchsiaAtomicUpdate() = default;
    ~FuchsiaAtomicUpdate() = default;
    FuchsiaAtomicUpdate(FuchsiaAtomicUpdate&&) = default;

    /// Adds a node to be updated. |size| contains the
    /// size in bytes of the node to be updated.
    void AddNodeUpdate(fuchsia::accessibility::semantics::Node node, size_t size);

    /// Adds a node to be deleted.
    void AddNodeDeletion(uint32_t id);

    /// clear the updates and deletions vectors
    void Clear();

    std::vector<std::pair<fuchsia::accessibility::semantics::Node, size_t>> updates;
    std::vector<uint32_t> deletions;
  };

  /// Holds a flutter semantic node and some extra info.
  /// In particular, it adds a screen_rect field to FlutterSemanticsNode.
  struct SemanticsNode {
    FlutterSemanticsNode data;
    FlutterRect screen_rect;
  };

  /// Adds a semantics node update to the buffer of node updates to apply.
  void AddSemanticsNodeUpdates(const FlutterSemanticsNode* update, size_t count);

  fuchsia::accessibility::semantics::Node GetRootNodeUpdate(size_t& node_size);

  /// Derives the BoundingBox of a Flutter semantics node from its
  /// rect and elevation.
  fuchsia::ui::gfx::BoundingBox GetNodeLocation(const FlutterSemanticsNode& node) const;

  /// Gets mat4 transformation from a Flutter semantics node.
  fuchsia::ui::gfx::mat4 GetNodeTransform(const FlutterSemanticsNode& node) const;

  /// Converts a Flutter semantics node's transformation to a mat4.
  fuchsia::ui::gfx::mat4 ConvertFlutterTransformToMat4(const FlutterTransformation transform) const;

  /// Derives the attributes for a Fuchsia semantics node from a Flutter
  /// semantics node.
  fuchsia::accessibility::semantics::Attributes GetNodeAttributes(const FlutterSemanticsNode& node,
                                                                  size_t* added_size) const;

  /// Derives the states for a Fuchsia semantics node from a Flutter semantics
  /// node.
  fuchsia::accessibility::semantics::States GetNodeStates(const FlutterSemanticsNode& node,
                                                          size_t* additional_size) const;

  /// Derives the set of supported actions for a Fuchsia semantics node from
  /// a Flutter semantics node.
  std::vector<fuchsia::accessibility::semantics::Action> GetNodeActions(
      const FlutterSemanticsNode& node, size_t* additional_size) const;

  /// Derives the role for a Fuchsia semantics node from a Flutter
  /// semantics node.
  fuchsia::accessibility::semantics::Role GetNodeRole(const FlutterSemanticsNode& node) const;

  /// Gets the set of reachable descendants from the given node id.
  std::unordered_set<int32_t> GetDescendants(int32_t node_id) const;

  /// Removes internal references to any dangling nodes from previous
  /// updates, and adds the nodes to be deleted to the current |atomic_update|.
  ///
  /// The node ids to be deleted are only collected at this point, and will be
  /// committed in the next call to |Apply()|.
  void PruneUnreachableNodes(FuchsiaAtomicUpdate* atomic_update);

  /// Updates the on-screen positions of accessibility elements,
  /// starting from the root element with an identity matrix.
  ///
  /// This should be called from Update.
  void UpdateScreenRects();

  /// Updates the on-screen positions of accessibility elements, starting
  /// from node_id and using the specified transform.
  ///
  /// Update calls this via UpdateScreenRects().
  void UpdateScreenRects(int32_t node_id, FlutterTransformation parent_transform,
                         std::unordered_set<int32_t>* visited_nodes);

  /// Traverses the semantics tree to find the node_id hit by the given x,y
  /// point.
  ///
  /// Assumes that SemanticsNode::screen_rect is up to date.
  std::optional<int32_t> GetHitNode(int32_t node_id, float x, float y);

  /// Returns whether the node is considered focusable.
  bool IsFocusable(const FlutterSemanticsNode& node) const;

  /// Converts a fuchsia::accessibility::semantics::Action to a
  /// flutterSemanticsAction.
  ///
  /// The node_id parameter is used for printing warnings about unsupported
  /// action types.
  std::optional<FlutterSemanticsAction> GetFlutterSemanticsAction(
      fuchsia::accessibility::semantics::Action fuchsia_action, uint32_t node_id);

  /// Applies the updates and deletions in |atomic_update|, sending them via
  /// |tree_ptr|.
  void Apply(FuchsiaAtomicUpdate* atomic_update);

  /// |fuchsia::accessibility::semantics::SemanticListener|
  void OnSemanticsModeChanged(bool enabled, OnSemanticsModeChangedCallback callback) override;

  // TODO(benbergkamp)
  // #if DEBUG
  /// Fills the inspect tree with debug information about the semantic tree.
  void FillInspectTree(int32_t flutter_node_id, int32_t current_level, inspect::Node inspect_node,
                       inspect::Inspector* inspector) const;
  // #endif // DEBUG

  SetSemanticsEnabledCallback set_semantics_enabled_callback_;
  DispatchSemanticsActionCallback dispatch_semantics_action_callback_;
  FlutterSemanticsNode root_flutter_semantics_node_;
  /// The pixel ratio used in the most recent AddSemanticsNodeUpdates function call
  float last_seen_view_pixel_ratio_ = 1.f;
  /// The pixel ratio that will be used in the next function call to AddSemanticsNodeUpdates
  /// Need to differenciate from last_seen, because there is special logic for handling a
  /// change in the pixel ratio
  float next_pixel_ratio_ = 1.f;

  fidl::Binding<fuchsia::accessibility::semantics::SemanticListener> binding_;
  fuchsia::accessibility::semantics::SemanticsManagerPtr fuchsia_semantics_manager_;
  fuchsia::accessibility::semantics::SemanticTreePtr tree_ptr_;

  /// This is the cache of all nodes we've sent to Fuchsia's SemanticsManager.
  /// Assists with pruning unreachable nodes and hit testing.
  std::unordered_map<int32_t, SemanticsNode> nodes_;
  bool semantics_enabled_;

  /// Queue of atomic updates to be sent to Fuchsia.
  std::shared_ptr<std::queue<FuchsiaAtomicUpdate>> atomic_updates_;
  FuchsiaAtomicUpdate current_atomic_update_;

  /// Node to publish inspect data.
  inspect::Node inspect_node_;

  // TODO(benbergkamp)
  // #if DEBUG
  /// Inspect node to store a dump of the semantic tree. Note that this only gets
  /// computed if requested, so it does not use memory to store the dump unless
  /// an explicit request is made.
  inspect::LazyNode inspect_node_tree_dump_;
  // #endif // DEBUG
};

}  // namespace embedder

#endif  // SRC_ACCESSIBILITY_BRIDGE_H_
