// 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 LIB_UI_SCENIC_CPP_TESTING_FAKE_FLATLAND_H_
#define LIB_UI_SCENIC_CPP_TESTING_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 <lib/ui/scenic/cpp/testing/fake_flatland_types.h>

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

namespace scenic {

// 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.
//
// The fake deliberately does not attempt to handle certain aspects of the real
// Flatland implementation which are complex or burdensome to implement:
//   + Rendering/interacting with Vulkan in any way
//   + Cross-flatland links between Views and Viewports
//   + Sysmem allocations
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)>;

  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) noexcept;
    ~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) noexcept;
    ~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 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, BufferCollectionBinding> buffer_collections;
  };

  FakeFlatland();
  ~FakeFlatland() override;
  // Delete copy and assignment ctors.
  FakeFlatland(const FakeFlatland&) = delete;
  FakeFlatland& operator=(const FakeFlatland&) = delete;

  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_; }

  GraphBindings& graph_bindings() { return graph_bindings_; }

  // 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);

  // Returns a request handler that binds the incoming FIDL requests to this
  // session's FIDL channels on the `dispatcher`.
  //
  // This can only be called once.
  fidl::InterfaceRequestHandler<fuchsia::ui::composition::Flatland> GetFlatlandRequestHandler(
      async_dispatcher_t* dispatcher = nullptr);
  fidl::InterfaceRequestHandler<fuchsia::ui::composition::Allocator> GetAllocatorRequestHandler(
      async_dispatcher_t* dispatcher = nullptr);

  // Disconnect the Flatland's FIDL channel with an error.
  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 returned frames and simulate scenic's normal
  // event flow.
  void FireOnFramePresentedEvent(
      fuchsia::scenic::scheduling::FramePresentedInfo frame_presented_info);

  // |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 SetScale(fuchsia::ui::composition::TransformId transform_id,
                fuchsia::math::VecF scale) override;

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

  // |fuchsia::ui::composition::Flatland|
  void SetOpacity(fuchsia::ui::composition::TransformId transform_id, float value) override;

  // |fuchsia::ui::composition::Flatland|
  void SetClipBoundary(fuchsia::ui::composition::TransformId transform_id,
                       std::unique_ptr<fuchsia::math::Rect> bounds) override;

  // |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 SetImageFlip(fuchsia::ui::composition::ContentId image_id,
                    fuchsia::ui::composition::ImageFlip flip) 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 SetHitRegions(fuchsia::ui::composition::TransformId transform_id,
                     std::vector<fuchsia::ui::composition::HitRegion> regions) override;

  // |fuchsia::ui::composition::Flatland|
  void SetInfiniteHitRegion(fuchsia::ui::composition::TransformId transform_id,
                            fuchsia::ui::composition::HitTestInteraction hit_test) override;

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

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

 private:
  void ReportBadOperationError();

  // True if any function has failed since the previous call to Present(), false otherwise.
  bool failure_since_previous_present_ = false;

  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_;
};

}  // namespace scenic

#endif  // LIB_UI_SCENIC_CPP_TESTING_FAKE_FLATLAND_H_
