// 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_SESSION_H_
#define FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_SESSION_H_

#include <fuchsia/images/cpp/fidl.h>
#include <fuchsia/scenic/scheduling/cpp/fidl.h>
#include <fuchsia/sysmem/cpp/fidl.h>
#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl_test_base.h>
#include <lib/async/dispatcher.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fidl/cpp/interface_handle.h>
#include <lib/fidl/cpp/interface_request.h>

#include <deque>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>  // For std::pair
#include <vector>

#include "flutter/fml/macros.h"

#include "fake_resources.h"

namespace flutter_runner::testing {

// A lightweight fake implementation of the scenic Session API, also called
// the "gfx API".  The fake has no side effects besides mutating its own
// internal state.
//
// The fake 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 scenic behavior of only processing commands when a `Present` is
//   invoked.
//   + It allows the user to inspect a snapshot of the session's local scene
//   graph at any moment in time, via the `SceneGraph()` accessor.
//   + The resources returned by `SceneGraph()` that the test uses for
//   inspection are decoupled from the resources managed internally by the
//   `FakeSession` 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 `FakeSession` and test to naturally use
//   `shared_ptr` for reference counting and mimic the real scenic behavior
//   exactly, instead of an awkward index-based API.
//   + It stores the various session resources generated by commands into a
//   std::unordered_map, and also correctly manages the resource lifetimes via
//   reference counting. This allows a resource to stay alive if its parent
//   still holds a reference to it, in the same way the real scenic
//   implementation would.
//
// Limitations:
//   +Error handling / session disconnection is still WIP.  FakeSession will
//   likely generate a CHECK in any place where the real scenic would disconnect
//   the session or send a ScenicError.
//   +root_presenter-only commands e.g. CreateLayer are not handled.
//   +Deprecated / obsolete commands are not handled.
//   +Input is not handled.
//   +Rendering is not handled.
//   +Cross-session links are not handled; the FakeSession only stores the
//   tokens provided to it in a FakeResourceState.
class FakeSession : public fuchsia::ui::scenic::testing::Session_TestBase {
 public:
  using PresentHandler =
      std::function<fuchsia::images::PresentationInfo(uint64_t,
                                                      std::vector<zx::event>,
                                                      std::vector<zx::event>)>;
  using Present2Handler =
      std::function<fuchsia::scenic::scheduling::FuturePresentationTimes(
          fuchsia::ui::scenic::Present2Args)>;
  using RequestPresentationTimesHandler =
      std::function<fuchsia::scenic::scheduling::FuturePresentationTimes(
          int64_t)>;
  using SessionAndListenerClientPair =
      std::pair<fidl::InterfaceHandle<fuchsia::ui::scenic::Session>,
                fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener>>;

  FakeSession();
  ~FakeSession() override = default;

  bool is_bound() const { return binding_.is_bound() && listener_.is_bound(); }

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

  const std::deque<fuchsia::ui::scenic::Command>& command_queue() const {
    return command_queue_;
  }

  // Generate a snapshot of the underlying scene graph for test inspection.
  FakeSceneGraph SceneGraph() const {
    return SceneGraphFromState(scene_graph_);
  }

  // Bind this session's FIDL channels to the `dispatcher` and allow processing
  // of incoming FIDL requests.
  SessionAndListenerClientPair Bind(async_dispatcher_t* dispatcher = nullptr);

  // Set a handler for `Present`-related FIDL calls' return values.
  void SetPresentHandler(PresentHandler present_handler);
  void SetPresent2Handler(Present2Handler present2_handler);
  void SetRequestPresentationTimesHandler(
      RequestPresentationTimesHandler request_presentation_times_handler);

  // Call after a successful `Present` or `Present2` to fire an
  // `OnFramePresented` event, which simulates the frame being displayed.
  void FireOnFramePresentedEvent(
      fuchsia::scenic::scheduling::FramePresentedInfo frame_presented_info);

  // Disconnect the session with an error.
  // TODO: Call this internally upon command error, instead of CHECK'ing.
  void DisconnectSession();

 private:
  // |fuchsia::ui::scenic::testing::Session_TestBase|
  void NotImplemented_(const std::string& name) override;

  // |fuchsia::ui::scenic::Session|
  void Enqueue(std::vector<fuchsia::ui::scenic::Command> cmds) override;

  // |fuchsia::ui::scenic::Session|
  void Present(uint64_t presentation_time,
               std::vector<zx::event> acquire_fences,
               std::vector<zx::event> release_fences,
               PresentCallback callback) override;

  // |fuchsia::ui::scenic::Session|
  void Present2(fuchsia::ui::scenic::Present2Args args,
                Present2Callback callback) override;

  // |fuchsia::ui::scenic::Session|
  void RequestPresentationTimes(
      int64_t requested_prediction_span,
      RequestPresentationTimesCallback callback) override;

  // |fuchsia::ui::scenic::Session|
  void RegisterBufferCollection(
      uint32_t buffer_id,
      fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> token)
      override;

  // |fuchsia::ui::scenic::Session|
  void DeregisterBufferCollection(uint32_t buffer_id) override;

  // |fuchsia::ui::scenic::Session|
  void SetDebugName(std::string debug_name) override;

  // Resource management.
  std::shared_ptr<FakeResourceState> GetResource(FakeResourceId id);
  void AddResource(FakeResourceState&& resource);
  void DetachResourceFromParent(
      std::shared_ptr<FakeResourceState> resource_ptr,
      std::shared_ptr<FakeResourceState> new_parent_ptr = nullptr);
  void PruneDeletedResourceRefs();

  // Apply queued commands and mutate the resource map.
  void ApplyCommands();
  void ApplyCreateResourceCmd(fuchsia::ui::gfx::CreateResourceCmd command);
  void ApplyReleaseResourceCmd(fuchsia::ui::gfx::ReleaseResourceCmd command);
  void ApplyAddChildCmd(fuchsia::ui::gfx::AddChildCmd command);
  void ApplyDetachCmd(fuchsia::ui::gfx::DetachCmd command);
  void ApplyDetachChildrenCmd(fuchsia::ui::gfx::DetachChildrenCmd command);
  void ApplySetTranslationCmd(fuchsia::ui::gfx::SetTranslationCmd command);
  void ApplySetScaleCmd(fuchsia::ui::gfx::SetScaleCmd command);
  void ApplySetRotationCmd(fuchsia::ui::gfx::SetRotationCmd command);
  void ApplySetAnchorCmd(fuchsia::ui::gfx::SetAnchorCmd command);
  void ApplySetOpacityCmd(fuchsia::ui::gfx::SetOpacityCmd command);
  void ApplySetShapeCmd(fuchsia::ui::gfx::SetShapeCmd command);
  void ApplySetMaterialCmd(fuchsia::ui::gfx::SetMaterialCmd command);
  void ApplySetClipPlanesCmd(fuchsia::ui::gfx::SetClipPlanesCmd command);
  void ApplySetViewPropertiesCmd(
      fuchsia::ui::gfx::SetViewPropertiesCmd command);
  void ApplySetHitTestBehaviorCmd(
      fuchsia::ui::gfx::SetHitTestBehaviorCmd command);
  void ApplySetSemanticVisibilityCmd(
      fuchsia::ui::gfx::SetSemanticVisibilityCmd command);
  void ApplySetTextureCmd(fuchsia::ui::gfx::SetTextureCmd command);
  void ApplySetColorCmd(fuchsia::ui::gfx::SetColorCmd command);
  void ApplySetEventMaskCmd(fuchsia::ui::gfx::SetEventMaskCmd command);
  void ApplySetLabelCmd(fuchsia::ui::gfx::SetLabelCmd command);
  void ApplySetEnableViewDebugBoundsCmd(
      fuchsia::ui::gfx::SetEnableDebugViewBoundsCmd command);
  void ApplySetViewHolderBoundsColorCmd(
      fuchsia::ui::gfx::SetViewHolderBoundsColorCmd command);
  void ApplyCreateMemory(FakeResourceId id, fuchsia::ui::gfx::MemoryArgs args);
  void ApplyCreateImage(FakeResourceId id, fuchsia::ui::gfx::ImageArgs args);
  void ApplyCreateImage2(FakeResourceId id, fuchsia::ui::gfx::ImageArgs2 args);
  void ApplyCreateImage3(FakeResourceId id, fuchsia::ui::gfx::ImageArgs3 args);
  void ApplyCreateImagePipe(FakeResourceId id,
                            fuchsia::ui::gfx::ImagePipeArgs args);
  void ApplyCreateImagePipe2(FakeResourceId id,
                             fuchsia::ui::gfx::ImagePipe2Args args);
  void ApplyCreateRectangle(FakeResourceId id,
                            fuchsia::ui::gfx::RectangleArgs args);
  void ApplyCreateRoundedRectangle(FakeResourceId id,
                                   fuchsia::ui::gfx::RoundedRectangleArgs args);
  void ApplyCreateCircle(FakeResourceId id, fuchsia::ui::gfx::CircleArgs args);
  void ApplyCreateMaterial(FakeResourceId id,
                           fuchsia::ui::gfx::MaterialArgs args);
  void ApplyCreateView(FakeResourceId id, fuchsia::ui::gfx::ViewArgs args);
  void ApplyCreateViewHolder(FakeResourceId id,
                             fuchsia::ui::gfx::ViewHolderArgs args);
  void ApplyCreateView(FakeResourceId id, fuchsia::ui::gfx::ViewArgs3 args);
  void ApplyCreateEntityNode(FakeResourceId id,
                             fuchsia::ui::gfx::EntityNodeArgs args);
  void ApplyCreateOpacityNode(FakeResourceId id,
                              fuchsia::ui::gfx::OpacityNodeArgsHACK args);
  void ApplyCreateShapeNode(FakeResourceId id,
                            fuchsia::ui::gfx::ShapeNodeArgs args);

  fidl::Binding<fuchsia::ui::scenic::Session> binding_;
  fuchsia::ui::scenic::SessionListenerPtr listener_;

  std::string debug_name_;

  FakeSceneGraphState scene_graph_;
  std::deque<fuchsia::ui::scenic::Command> command_queue_;

  // This map is used to cache parent refs for `AddChildCmd`.
  //
  // Ideally we would like to map weak(parent) -> weak(child), 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<FakeResourceState*,
                     std::pair<std::weak_ptr<FakeResourceState>,
                               std::weak_ptr<FakeResourceState>>>
      parents_map_;

  PresentHandler present_handler_;
  Present2Handler present2_handler_;
  RequestPresentationTimesHandler request_presentation_times_handler_;

  FML_DISALLOW_COPY_AND_ASSIGN(FakeSession);
};

}  // namespace flutter_runner::testing

#endif  // FLUTTER_SHELL_PLATFORM_FUCHSIA_FLUTTER_TESTS_FAKES_SCENIC_FAKE_SESSION_H_
