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

#ifndef FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_FLATLAND_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_FLATLAND_H_

#include <fuchsia/math/cpp/fidl.h>
#include <fuchsia/scenic/scheduling/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
#include <fuchsia/ui/composition/cpp/fidl.h>
#include <fuchsia/ui/composition/cpp/fidl_test_base.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/async/dispatcher.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/interface_request.h>

#include <cstdint>
#include <functional>
#include <string>
#include <unordered_map>
#include <vector>

#include "flutter/fml/logging.h"
#include "flutter/fml/macros.h"

#include "fake_flatland_types.h"

namespace flutter_runner::testing {

// A lightweight fake implementation of the Flatland API.
//
// The fake has no side effects besides mutating its own internal state
// according to the rules of interacting with the Flatland API.  It makes that
// internal state available for inspection by a test.
//
// Thus it allows tests to do a few things that would be difficult using either
// a mock implementation or the real implementation:
//   + It allows the user to hook `Present` invocations and respond with
//   stubbed-out `FuturePresentationTimes`, but more crucially it mimics the
//   real Flatland behavior of only processing commands when a `Present` is
//   invoked.
//   + It allows the user to inspect a snapshot of the scene graph at any moment
//   in time, via the `SceneGraph()` accessor.
//   + It stores the various Flatland transforms and content generated by
//   commands into a std::unordered_map, and also correctly manages the
//   transform and content lifetimes via reference counting. This allows a
//   given transform or content to stay alive if its parent still holds a
//   reference to it, in the same way the real Flatland implementation would.
//   + The resources returned by `SceneGraph()` that the test uses for
//   inspection are decoupled from the resources managed internally by the
//   `FakeFlatland` itself -- they are a snapshot of the scene graph at that
//   moment in time, with all snapshot state being cloned from the underlying
//   scene graph state.  This allows the `FakeFlatland` and test to naturally
//   use `shared_ptr` for reference counting and mimic the real Flatland
//   behavior exactly, instead of an awkward index-based API.
//   + TODO(fxb/85619):  Allow injecting {touch,mouse,focus,views} events using
//   the ViewBoundProtocols and {ParentViewport,ChildView}Watcher.
//   + TODO(fxb/85619):  Error handling / flatland disconnection is still WIP.
//   FakeFlatland will likely generate a CHECK in any place where the real
//   Flatland would disconnect or send a FlatlandError.
//
// The fake deliberately does not attempt to handle certain aspects of the real
// Flatland implemntation which are complex or burdensome to implement:
//   +Rendering/interacting with Vulkan in any way
//   +Cross-flatland links between Views and Viewports.
class FakeFlatland
    : public fuchsia::ui::composition::testing::Allocator_TestBase,
      public fuchsia::ui::composition::testing::Flatland_TestBase {
 public:
  using PresentHandler =
      std::function<void(fuchsia::ui::composition::PresentArgs)>;

  FakeFlatland();
  ~FakeFlatland() override;

  bool is_allocator_connected() const { return allocator_binding_.is_bound(); }

  bool is_flatland_connected() const { return flatland_binding_.is_bound(); }

  const std::string& debug_name() const { return debug_name_; }

  const FakeGraph& graph() { return current_graph_; }

  // Bind this instance's Flatland FIDL channel to the `dispatcher` and allow
  // processing of incoming FIDL requests.
  //
  // This can only be called once.
  fuchsia::ui::composition::AllocatorHandle ConnectAllocator(
      async_dispatcher_t* dispatcher = nullptr);

  // Bind this instance's Allocator FIDL channel to the `dispatcher` and allow
  // processing of incoming FIDL requests.
  //
  // This can only be called once.
  fuchsia::ui::composition::FlatlandHandle ConnectFlatland(
      async_dispatcher_t* dispatcher = nullptr);

  // Disconnect the Flatland's FIDL channel with an error.
  // TODO(fxb/85619): Call this internally upon command error, instead of
  // CHECK'ing.
  void Disconnect(fuchsia::ui::composition::FlatlandError error);

  // Set a handler for `Present`-related FIDL calls' return values.
  void SetPresentHandler(PresentHandler present_handler);

  // Fire an `OnNextFrameBegin` event.  Call this first after a `Present` in
  // order to give additional present tokens to the client and simulate scenic's
  // normal event flow.
  void FireOnNextFrameBeginEvent(
      fuchsia::ui::composition::OnNextFrameBeginValues
          on_next_frame_begin_values);

  // Fire an `OnFramePresented` event.  Call this second after a `Present` in
  // order to inform the client of retured frames and simulate scenic's normal
  // event flow.
  void FireOnFramePresentedEvent(
      fuchsia::scenic::scheduling::FramePresentedInfo frame_presented_info);

 private:
  struct ParentViewportWatcher : public fuchsia::ui::composition::testing::
                                     ParentViewportWatcher_TestBase {
   public:
    ParentViewportWatcher(
        fuchsia::ui::views::ViewCreationToken view_token,
        fuchsia::ui::views::ViewIdentityOnCreation view_identity,
        fuchsia::ui::composition::ViewBoundProtocols view_protocols,
        fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
            parent_viewport_watcher,
        async_dispatcher_t* dispatcher);
    ParentViewportWatcher(ParentViewportWatcher&& other);
    ~ParentViewportWatcher() override;

    // |fuchsia::ui::composition::testing::ParentViewportWatcher_TestBase|
    void NotImplemented_(const std::string& name) override;

    // |fuchsia::ui::composition::ParentViewportWatcher|
    void GetLayout(GetLayoutCallback callback) override;

    // |fuchsia::ui::composition::ParentViewportWatcher|
    void GetStatus(GetStatusCallback callback) override;

    fuchsia::ui::views::ViewCreationToken view_token;
    fuchsia::ui::views::ViewIdentityOnCreation view_identity;
    fuchsia::ui::composition::ViewBoundProtocols view_protocols;
    fidl::Binding<fuchsia::ui::composition::ParentViewportWatcher>
        parent_viewport_watcher;
  };

  struct ChildViewWatcher
      : public fuchsia::ui::composition::testing::ChildViewWatcher_TestBase {
   public:
    ChildViewWatcher(
        fuchsia::ui::views::ViewportCreationToken viewport_token,
        fidl::InterfaceRequest<fuchsia::ui::composition::ChildViewWatcher>
            child_view_watcher,
        async_dispatcher_t* dispatcher);
    ChildViewWatcher(ChildViewWatcher&& other);
    ~ChildViewWatcher() override;

    // |fuchsia::ui::composition::testing::ChildViewWatcher_TestBase|
    void NotImplemented_(const std::string& name) override;

    // |fuchsia::ui::composition::ChildViewWatcher|
    void GetStatus(GetStatusCallback callback) override;

    fuchsia::ui::views::ViewportCreationToken viewport_token;
    fidl::Binding<fuchsia::ui::composition::ChildViewWatcher>
        child_view_watcher;
  };

  struct ImageBinding {
    fuchsia::ui::composition::BufferCollectionImportToken import_token;
  };

  struct BufferCollectionBinding {
    fuchsia::ui::composition::BufferCollectionExportToken export_token;
    fuchsia::sysmem::BufferCollectionTokenHandle sysmem_token;

    fuchsia::ui::composition::RegisterBufferCollectionUsage usage;
  };

  struct GraphBindings {
    std::optional<std::pair<zx_koid_t, ParentViewportWatcher>> viewport_watcher;
    std::unordered_map<zx_koid_t, ChildViewWatcher> view_watchers;
    std::unordered_map<zx_koid_t, ImageBinding> images;
    std::unordered_map<zx_koid_t, BufferCollectionBinding> buffer_collections;
  };

  // |fuchsia::ui::composition::testing::Allocator_TestBase|
  // |fuchsia::ui::composition::testing::Flatland_TestBase|
  void NotImplemented_(const std::string& name) override;

  // |fuchsia::ui::composition::testing::Allocator|
  void RegisterBufferCollection(
      fuchsia::ui::composition::RegisterBufferCollectionArgs args,
      RegisterBufferCollectionCallback callback) override;

  // |fuchsia::ui::composition::Flatland|
  void Present(fuchsia::ui::composition::PresentArgs args) override;

  // |fuchsia::ui::composition::Flatland|
  void CreateView(
      fuchsia::ui::views::ViewCreationToken token,
      fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
          parent_viewport_watcher) override;

  // |fuchsia::ui::composition::Flatland|
  void CreateView2(
      fuchsia::ui::views::ViewCreationToken token,
      fuchsia::ui::views::ViewIdentityOnCreation view_identity,
      fuchsia::ui::composition::ViewBoundProtocols view_protocols,
      fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
          parent_viewport_watcher) override;

  // |fuchsia::ui::composition::Flatland|
  void CreateTransform(
      fuchsia::ui::composition::TransformId transform_id) override;

  // |fuchsia::ui::composition::Flatland|
  void SetTranslation(fuchsia::ui::composition::TransformId transform_id,
                      fuchsia::math::Vec translation) override;

  // |fuchsia::ui::composition::Flatland|
  void SetOrientation(
      fuchsia::ui::composition::TransformId transform_id,
      fuchsia::ui::composition::Orientation orientation) override;

  // |fuchsia::ui::composition::Flatland|
  void SetClipBounds(fuchsia::ui::composition::TransformId transform_id,
                     fuchsia::math::Rect clip_bounds) override;

  // TODO(fxbug.dev/89111): Re-enable once SDK rolls.
  //   // |fuchsia::ui::composition::Flatland|
  //   void SetImageOpacity(fuchsia::ui::composition::ContentId image_id,
  //                        float opacity) override;

  // |fuchsia::ui::composition::Flatland|
  void AddChild(
      fuchsia::ui::composition::TransformId parent_transform_id,
      fuchsia::ui::composition::TransformId child_transform_id) override;

  // |fuchsia::ui::composition::Flatland|
  void RemoveChild(
      fuchsia::ui::composition::TransformId parent_transform_id,
      fuchsia::ui::composition::TransformId child_transform_id) override;

  // |fuchsia::ui::composition::Flatland|
  void SetContent(fuchsia::ui::composition::TransformId transform_id,
                  fuchsia::ui::composition::ContentId content_id) override;

  // |fuchsia::ui::composition::Flatland|
  void SetRootTransform(
      fuchsia::ui::composition::TransformId transform_id) override;

  // |fuchsia::ui::composition::Flatland|
  void CreateViewport(
      fuchsia::ui::composition::ContentId viewport_id,
      fuchsia::ui::views::ViewportCreationToken token,
      fuchsia::ui::composition::ViewportProperties properties,
      fidl::InterfaceRequest<fuchsia::ui::composition::ChildViewWatcher>
          child_view_watcher) override;

  // |fuchsia::ui::composition::Flatland|
  void CreateImage(
      fuchsia::ui::composition::ContentId image_id,
      fuchsia::ui::composition::BufferCollectionImportToken import_token,
      uint32_t vmo_index,
      fuchsia::ui::composition::ImageProperties properties) override;

  // |fuchsia::ui::composition::Flatland|
  void SetImageSampleRegion(fuchsia::ui::composition::ContentId image_id,
                            fuchsia::math::RectF rect) override;

  // |fuchsia::ui::composition::Flatland|
  void SetImageDestinationSize(fuchsia::ui::composition::ContentId image_id,
                               fuchsia::math::SizeU size) override;

  // |fuchsia::ui::composition::Flatland|
  void SetImageBlendingFunction(
      fuchsia::ui::composition::ContentId image_id,
      fuchsia::ui::composition::BlendMode blend_mode) override;

  // |fuchsia::ui::composition::Flatland|
  void SetViewportProperties(
      fuchsia::ui::composition::ContentId viewport_id,
      fuchsia::ui::composition::ViewportProperties properties) override;

  // |fuchsia::ui::composition::Flatland|
  void ReleaseTransform(
      fuchsia::ui::composition::TransformId transform_id) override;

  // |fuchsia::ui::composition::Flatland|
  void ReleaseViewport(fuchsia::ui::composition::ContentId viewport_id,
                       ReleaseViewportCallback callback) override;

  // |fuchsia::ui::composition::Flatland|
  void ReleaseImage(fuchsia::ui::composition::ContentId image_id) override;

  // |fuchsia::ui::composition::Flatland|
  void Clear() override;

  // |fuchsia::ui::composition::Flatland|
  void SetDebugName(std::string debug_name) override;

  fidl::Binding<fuchsia::ui::composition::Allocator> allocator_binding_;
  fidl::Binding<fuchsia::ui::composition::Flatland> flatland_binding_;
  GraphBindings graph_bindings_;
  PresentHandler present_handler_;

  FakeGraph pending_graph_;
  FakeGraph current_graph_;

  // This map is used to cache parent refs for `AddChild` and `RemoveChild`.
  //
  // Ideally we would like to map weak(child) -> weak(parent), but std::weak_ptr
  // cannot be the Key for an associative container. Instead we key on the raw
  // parent pointer and store pair(weak(parent), weak(child)) in the map.
  std::unordered_map<
      FakeGraph::TransformIdKey,
      std::pair<std::weak_ptr<FakeTransform>, std::weak_ptr<FakeTransform>>>
      parents_map_;

  std::string debug_name_;

  FML_DISALLOW_COPY_AND_ASSIGN(FakeFlatland);
};

}  // namespace flutter_runner::testing

#endif  // FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_FLATLAND_H_
