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

#include "flutter/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h"

#include <fuchsia/sysmem/cpp/fidl.h>
#include <fuchsia/ui/gfx/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <fuchsia/ui/views/cpp/fidl.h>
#include <lib/async-testing/test_loop.h>
#include <lib/async/dispatcher.h>
#include <lib/fidl/cpp/interface_request.h>
#include <lib/fidl/cpp/synchronous_interface_ptr.h>
#include <lib/inspect/cpp/inspect.h>
#include <lib/ui/scenic/cpp/commands.h>
#include <lib/ui/scenic/cpp/view_ref_pair.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>

#include <algorithm>
#include <cstdint>
#include <functional>
#include <memory>
#include <string>
#include <vector>

#include "flutter/flow/embedded_views.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/time/time_delta.h"
#include "flutter/fml/time/time_point.h"
#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkSize.h"
#include "third_party/skia/include/core/SkSurface.h"

#include "fakes/scenic/fake_resources.h"
#include "fakes/scenic/fake_session.h"
#include "flutter/shell/platform/fuchsia/flutter/surface_producer.h"

#include "gmock/gmock.h"  // For EXPECT_THAT and matchers
#include "gtest/gtest.h"

using fuchsia::scenic::scheduling::FramePresentedInfo;
using fuchsia::scenic::scheduling::FuturePresentationTimes;
using fuchsia::scenic::scheduling::PresentReceivedInfo;
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::FieldsAre;
using ::testing::IsEmpty;
using ::testing::IsNull;
using ::testing::Matcher;
using ::testing::Pointee;
using ::testing::SizeIs;
using ::testing::VariantWith;

namespace flutter_runner::testing {
namespace {

class FakeSurfaceProducerSurface : public SurfaceProducerSurface {
 public:
  explicit FakeSurfaceProducerSurface(scenic::Session* session,
                                      const SkISize& size,
                                      uint32_t buffer_id)
      : session_(session),
        surface_(SkSurface::MakeNull(size.width(), size.height())),
        buffer_id_(buffer_id) {
    FML_CHECK(session_);
    FML_CHECK(buffer_id_ != 0);

    fuchsia::sysmem::BufferCollectionTokenSyncPtr token;
    buffer_binding_ = token.NewRequest();

    image_id_ = session_->AllocResourceId();
    session_->RegisterBufferCollection(buffer_id_, std::move(token));
    session_->Enqueue(scenic::NewCreateImage2Cmd(
        image_id_, surface_->width(), surface_->height(), buffer_id_, 0));
  }
  ~FakeSurfaceProducerSurface() override {
    session_->DeregisterBufferCollection(buffer_id_);
    session_->Enqueue(scenic::NewReleaseResourceCmd(image_id_));
  }

  bool IsValid() const override { return true; }

  SkISize GetSize() const override {
    return SkISize::Make(surface_->width(), surface_->height());
  }

  void SetImageId(uint32_t image_id) override { FAIL(); }
  uint32_t GetImageId() override { return image_id_; }

  sk_sp<SkSurface> GetSkiaSurface() const override { return surface_; }

  fuchsia::ui::composition::BufferCollectionImportToken
  GetBufferCollectionImportToken() override {
    return fuchsia::ui::composition::BufferCollectionImportToken{};
  }

  zx::event GetAcquireFence() override { return zx::event{}; }

  zx::event GetReleaseFence() override { return zx::event{}; }

  void SetReleaseImageCallback(
      ReleaseImageCallback release_image_callback) override {}

  size_t AdvanceAndGetAge() override { return 0; }
  bool FlushSessionAcquireAndReleaseEvents() override { return true; }
  void SignalWritesFinished(
      const std::function<void(void)>& on_writes_committed) override {}

 private:
  scenic::Session* session_;

  sk_sp<SkSurface> surface_;

  fidl::InterfaceRequest<fuchsia::sysmem::BufferCollectionToken>
      buffer_binding_;
  FakeResourceId image_id_{kInvalidFakeResourceId};
  uint32_t buffer_id_{0};
};

class FakeSurfaceProducer : public SurfaceProducer {
 public:
  explicit FakeSurfaceProducer(scenic::Session* session) : session_(session) {}
  ~FakeSurfaceProducer() override = default;

  // |SurfaceProducer|
  GrDirectContext* gr_context() const override { return nullptr; }

  // |SurfaceProducer|
  std::unique_ptr<SurfaceProducerSurface> ProduceOffscreenSurface(
      const SkISize& size) override {
    return nullptr;
  }

  // |SurfaceProducer|
  std::unique_ptr<SurfaceProducerSurface> ProduceSurface(
      const SkISize& size) override {
    return std::make_unique<FakeSurfaceProducerSurface>(session_, size,
                                                        buffer_id_++);
  }

  // |SurfaceProducer|
  void SubmitSurfaces(
      std::vector<std::unique_ptr<SurfaceProducerSurface>> surfaces) override {}

 private:
  scenic::Session* session_;

  uint32_t buffer_id_{1};
};

std::string GetCurrentTestName() {
  return ::testing::UnitTest::GetInstance()->current_test_info()->name();
}

zx_koid_t GetKoid(zx_handle_t handle) {
  if (handle == ZX_HANDLE_INVALID) {
    return ZX_KOID_INVALID;
  }

  zx_info_handle_basic_t info;
  zx_status_t status = zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &info,
                                          sizeof(info), nullptr, nullptr);
  return status == ZX_OK ? info.koid : ZX_KOID_INVALID;
}

zx_koid_t GetPeerKoid(zx_handle_t handle) {
  if (handle == ZX_HANDLE_INVALID) {
    return ZX_KOID_INVALID;
  }

  zx_info_handle_basic_t info;
  zx_status_t status = zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &info,
                                          sizeof(info), nullptr, nullptr);
  return status == ZX_OK ? info.related_koid : ZX_KOID_INVALID;
}

MATCHER_P(MaybeIsEmpty, assert_empty, "") {
  return assert_empty ? ExplainMatchResult(IsEmpty(), arg, result_listener)
                      : ExplainMatchResult(_, arg, result_listener);
}

Matcher<FakeSceneGraph> IsEmptySceneGraph() {
  return FieldsAre(IsEmpty(), IsEmpty(), IsEmpty(), kInvalidFakeResourceId);
}

void AssertRootSceneGraph(const FakeSceneGraph& scene_graph,
                          bool assert_empty) {
  ASSERT_NE(scene_graph.root_view_id, kInvalidFakeResourceId);
  ASSERT_EQ(scene_graph.resource_map.count(scene_graph.root_view_id), 1u);
  auto scene_graph_root =
      scene_graph.resource_map.find(scene_graph.root_view_id);
  ASSERT_THAT(
      scene_graph_root->second,
      Pointee(FieldsAre(
          scene_graph.root_view_id, "", FakeResource::kDefaultEmptyEventMask,
          VariantWith<FakeView>(FieldsAre(
              _, _, _, _,
              ElementsAre(Pointee(FieldsAre(
                  _, "Flutter::MetricsWatcher",
                  fuchsia::ui::gfx::kMetricsEventMask,
                  VariantWith<FakeEntityNode>(FieldsAre(
                      FieldsAre(
                          ElementsAre(Pointee(FieldsAre(
                              _, "Flutter::LayerTree",
                              FakeResource::kDefaultEmptyEventMask,
                              VariantWith<FakeEntityNode>(FieldsAre(
                                  FieldsAre(MaybeIsEmpty(assert_empty),
                                            FakeNode::kDefaultZeroRotation,
                                            FakeNode::kDefaultOneScale,
                                            FakeNode::kDefaultZeroTranslation,
                                            FakeNode::kDefaultZeroAnchor,
                                            FakeNode::kIsHitTestable,
                                            FakeNode::kIsSemanticallyVisible),
                                  IsEmpty()))))),
                          FakeNode::kDefaultZeroRotation,
                          FakeNode::kDefaultOneScale,
                          FakeNode::kDefaultZeroTranslation,
                          FakeNode::kDefaultZeroAnchor,
                          FakeNode::kIsHitTestable,
                          FakeNode::kIsSemanticallyVisible),
                      IsEmpty()))))),
              FakeView::kDebugBoundsDisbaled)))));
}

void ExpectRootSceneGraph(
    const FakeSceneGraph& scene_graph,
    const std::string& debug_name,
    const fuchsia::ui::views::ViewHolderToken& view_holder_token,
    const fuchsia::ui::views::ViewRef& view_ref) {
  AssertRootSceneGraph(scene_graph, true);

  // These are safe to do unchecked due to `AssertRootSceneGraph` above.
  auto root_view_it = scene_graph.resource_map.find(scene_graph.root_view_id);
  auto* root_view_state = std::get_if<FakeView>(&root_view_it->second->state);
  EXPECT_EQ(root_view_state->token, GetPeerKoid(view_holder_token.value.get()));
  EXPECT_EQ(root_view_state->control_ref,
            GetPeerKoid(view_ref.reference.get()));
  EXPECT_EQ(root_view_state->view_ref, GetKoid(view_ref.reference.get()));
  EXPECT_EQ(root_view_state->debug_name, debug_name);
  EXPECT_EQ(scene_graph.resource_map.size(), 3u);
}

/// Verifies the scene subgraph for a particular flutter embedder layer.
///
/// ARGUMENTS
///
/// scenic_node: The root of the layer's scenic subgraph.
///
/// layer_size: The expected dimensions of the layer's image.
///
/// flutter_layer_index: This layer's 0-indexed position in the list of
/// flutter layers present in this frame, sorted in paint order.
///
/// paint_regions: List of non-overlapping rects, in canvas coordinate space,
/// where content was drawn. For each "paint region" present in the frame, the
/// embedder reports a corresponding "hit region" to scenic as a hittable
/// ShapeNode. ShapeNodes are centered at (0, 0), by default, so they must be
/// translated to match the locations of the corresopnding paint regions.
void ExpectImageCompositorLayer(const FakeResource& scenic_node,
                                const SkISize layer_size,
                                size_t flutter_layer_index,
                                std::vector<SkRect> paint_regions) {
  const SkSize float_layer_size =
      SkSize::Make(layer_size.width(), layer_size.height());
  const float views_under_layer_depth =
      flutter_layer_index *
      GfxExternalViewEmbedder::kScenicZElevationForPlatformView;
  const float layer_depth =
      flutter_layer_index *
          GfxExternalViewEmbedder::kScenicZElevationBetweenLayers +
      views_under_layer_depth;
  const float layer_opacity =
      (flutter_layer_index == 0)
          ? GfxExternalViewEmbedder::kBackgroundLayerOpacity / 255.f
          : GfxExternalViewEmbedder::kOverlayLayerOpacity / 255.f;

  EXPECT_THAT(
      scenic_node,
      FieldsAre(
          _, "Flutter::Layer", FakeResource::kDefaultEmptyEventMask,
          VariantWith<FakeEntityNode>(FieldsAre(
              FieldsAre(
                  // Verify children separately below, since the
                  // expected number of children may vary across
                  // different test cases that call this method.
                  _, FakeNode::kDefaultZeroRotation, FakeNode::kDefaultOneScale,
                  FakeNode::kDefaultZeroTranslation,
                  FakeNode::kDefaultZeroAnchor, FakeNode::kIsHitTestable,
                  FakeNode::kIsSemanticallyVisible),
              _))));

  const auto* layer_node_state =
      std::get_if<FakeEntityNode>(&scenic_node.state);
  ASSERT_TRUE(layer_node_state);

  const auto& layer_node_children = layer_node_state->node_state.children;

  // The layer entity node should have a child node for the image, and
  // separate children for each of the hit regions.
  ASSERT_EQ(layer_node_children.size(), paint_regions.size() + 1);

  // Verify image node.
  EXPECT_THAT(
      layer_node_children[0],
      Pointee(FieldsAre(
          _, "Flutter::Layer::Image", FakeResource::kDefaultEmptyEventMask,
          VariantWith<FakeShapeNode>(FieldsAre(
              FieldsAre(IsEmpty(), FakeNode::kDefaultZeroRotation,
                        FakeNode::kDefaultOneScale,
                        std::array<float, 3>{float_layer_size.width() / 2.f,
                                             float_layer_size.height() / 2.f,
                                             -layer_depth},
                        FakeNode::kDefaultZeroAnchor,
                        FakeNode::kIsNotHitTestable,
                        FakeNode::kIsNotSemanticallyVisible),
              Pointee(
                  FieldsAre(_, "", FakeResource::kDefaultEmptyEventMask,
                            VariantWith<FakeShape>(
                                FieldsAre(VariantWith<FakeShape::RectangleDef>(
                                    FieldsAre(float_layer_size.width(),
                                              float_layer_size.height())))))),
              Pointee(FieldsAre(
                  _, "", FakeResource::kDefaultEmptyEventMask,
                  VariantWith<FakeMaterial>(FieldsAre(
                      Pointee(FieldsAre(
                          _, "", FakeResource::kDefaultEmptyEventMask,
                          VariantWith<FakeImage>(FieldsAre(
                              VariantWith<FakeImage::Image2Def>(
                                  FieldsAre(_, 0, float_layer_size.width(),
                                            float_layer_size.height())),
                              IsNull())))),
                      std::array<float, 4>{1.f, 1.f, 1.f,
                                           layer_opacity})))))))));

  // Verify hit regions.
  for (size_t i = 0; i < paint_regions.size(); ++i) {
    ASSERT_LT(i, layer_node_children.size());
    const auto& paint_region = paint_regions[i];
    EXPECT_THAT(
        layer_node_children[i + 1],
        Pointee(FieldsAre(
            _, "Flutter::Layer::HitRegion",
            FakeResource::kDefaultEmptyEventMask,
            VariantWith<FakeShapeNode>(FieldsAre(
                FieldsAre(IsEmpty(), FakeNode::kDefaultZeroRotation,
                          FakeNode::kDefaultOneScale,
                          std::array<float, 3>{
                              paint_region.x() + paint_region.width() / 2.f,
                              paint_region.y() + paint_region.height() / 2.f,
                              -layer_depth},
                          FakeNode::kDefaultZeroAnchor,
                          FakeNode::kIsHitTestable,
                          FakeNode::kIsSemanticallyVisible),
                Pointee(FieldsAre(
                    _, "", FakeResource::kDefaultEmptyEventMask,
                    VariantWith<FakeShape>(FieldsAre(
                        VariantWith<FakeShape::RectangleDef>(FieldsAre(
                            paint_region.width(), paint_region.height())))))),
                IsNull())))));
  }
}

void ExpectViewCompositorLayer(const FakeResource& scenic_node,
                               const fuchsia::ui::views::ViewToken& view_token,
                               const flutter::EmbeddedViewParams& view_params,
                               size_t flutter_layer_index) {
  const float views_under_layer_depth =
      flutter_layer_index > 0
          ? (flutter_layer_index - 1) *
                GfxExternalViewEmbedder::kScenicZElevationForPlatformView
          : 0.f;
  const float layer_depth =
      flutter_layer_index *
          GfxExternalViewEmbedder::kScenicZElevationBetweenLayers +
      views_under_layer_depth;
  EXPECT_THAT(
      scenic_node,
      FieldsAre(
          _, _ /*"Flutter::PlatformView::OpacityMutator" */,
          FakeResource::kDefaultEmptyEventMask,
          VariantWith<FakeOpacityNode>(FieldsAre(
              FieldsAre(
                  ElementsAre(Pointee(FieldsAre(
                      _, _ /*"Flutter::PlatformView::TransformMutator" */,
                      FakeResource::kDefaultEmptyEventMask,
                      VariantWith<FakeEntityNode>(FieldsAre(
                          FieldsAre(
                              ElementsAre(Pointee(FieldsAre(
                                  _, "", FakeResource::kDefaultEmptyEventMask,
                                  VariantWith<FakeViewHolder>(FieldsAre(
                                      FieldsAre(
                                          IsEmpty(),
                                          FakeNode::kDefaultZeroRotation,
                                          FakeNode::kDefaultOneScale,
                                          FakeNode::kDefaultZeroTranslation,
                                          FakeNode::kDefaultZeroAnchor,
                                          FakeNode::kIsHitTestable,
                                          FakeNode::kIsSemanticallyVisible),
                                      GetPeerKoid(view_token.value.get()),
                                      "Flutter::PlatformView",
                                      fuchsia::ui::gfx::ViewProperties{
                                          .bounding_box =
                                              fuchsia::ui::gfx::BoundingBox{
                                                  .min = {0.f, 0.f, -1000.f},
                                                  .max =
                                                      {view_params.sizePoints()
                                                           .width(),
                                                       view_params.sizePoints()
                                                           .height(),
                                                       0.f},
                                              }},
                                      FakeViewHolder::
                                          kDefaultBoundsColorWhite))))),
                              FakeNode::kDefaultZeroRotation,
                              FakeNode::kDefaultOneScale,
                              std::array<float, 3>{0.f, 0.f, -layer_depth},
                              FakeNode::kDefaultZeroAnchor,
                              FakeNode::kIsHitTestable,
                              FakeNode::kIsSemanticallyVisible),
                          IsEmpty()))))),
                  FakeNode::kDefaultZeroRotation, FakeNode::kDefaultOneScale,
                  FakeNode::kDefaultZeroTranslation,
                  FakeNode::kDefaultZeroAnchor, FakeNode::kIsHitTestable,
                  FakeNode::kIsSemanticallyVisible),
              FakeOpacityNode::kDefaultOneOpacity))));
}

std::vector<FakeResource> ExtractLayersFromSceneGraph(
    const FakeSceneGraph& scene_graph) {
  AssertRootSceneGraph(scene_graph, false);

  // These are safe to do unchecked due to `AssertRootSceneGraph` above.
  auto root_view_it = scene_graph.resource_map.find(scene_graph.root_view_id);
  auto* root_view_state = std::get_if<FakeView>(&root_view_it->second->state);
  auto* metrics_watcher_state =
      std::get_if<FakeEntityNode>(&root_view_state->children[0]->state);
  auto* layer_tree_state = std::get_if<FakeEntityNode>(
      &metrics_watcher_state->node_state.children[0]->state);

  std::vector<FakeResource> scenic_layers;
  for (auto& layer_resource : layer_tree_state->node_state.children) {
    scenic_layers.push_back(*layer_resource);
  }

  return scenic_layers;
}

void DrawSimpleFrame(GfxExternalViewEmbedder& external_view_embedder,
                     SkISize frame_size,
                     float frame_dpr,
                     std::function<void(SkCanvas*)> draw_callback) {
  external_view_embedder.BeginFrame(frame_size, nullptr, frame_dpr, nullptr);
  {
    SkCanvas* root_canvas = external_view_embedder.GetRootCanvas();
    external_view_embedder.PostPrerollAction(nullptr);
    draw_callback(root_canvas);
  }
  external_view_embedder.EndFrame(false, nullptr);
  flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
  external_view_embedder.SubmitFrame(
      nullptr, std::make_unique<flutter::SurfaceFrame>(
                   nullptr, framebuffer_info,
                   [](const flutter::SurfaceFrame& surface_frame,
                      SkCanvas* canvas) { return true; }));
}

void DrawFrameWithView(GfxExternalViewEmbedder& external_view_embedder,
                       SkISize frame_size,
                       float frame_dpr,
                       int view_id,
                       flutter::EmbeddedViewParams& view_params,
                       std::function<void(SkCanvas*)> background_draw_callback,
                       std::function<void(SkCanvas*)> overlay_draw_callback) {
  external_view_embedder.BeginFrame(frame_size, nullptr, frame_dpr, nullptr);
  {
    SkCanvas* root_canvas = external_view_embedder.GetRootCanvas();
    external_view_embedder.PrerollCompositeEmbeddedView(
        view_id, std::make_unique<flutter::EmbeddedViewParams>(view_params));
    external_view_embedder.PostPrerollAction(nullptr);
    background_draw_callback(root_canvas);
    SkCanvas* overlay_canvas =
        external_view_embedder.CompositeEmbeddedView(view_id);
    overlay_draw_callback(overlay_canvas);
  }
  external_view_embedder.EndFrame(false, nullptr);
  flutter::SurfaceFrame::FramebufferInfo framebuffer_info;
  external_view_embedder.SubmitFrame(
      nullptr, std::make_unique<flutter::SurfaceFrame>(
                   nullptr, framebuffer_info,
                   [](const flutter::SurfaceFrame& surface_frame,
                      SkCanvas* canvas) { return true; }));
}

FramePresentedInfo MakeFramePresentedInfoForOnePresent(
    int64_t latched_time,
    int64_t frame_presented_time) {
  std::vector<PresentReceivedInfo> present_infos;
  present_infos.emplace_back();
  present_infos.back().set_present_received_time(0);
  present_infos.back().set_latched_time(0);
  return FramePresentedInfo{
      .actual_presentation_time = 0,
      .presentation_infos = std::move(present_infos),
      .num_presents_allowed = 1,
  };
}

};  // namespace

class GfxExternalViewEmbedderTest
    : public ::testing::Test,
      public fuchsia::ui::scenic::SessionListener {
 protected:
  GfxExternalViewEmbedderTest()
      : session_subloop_(loop_.StartNewLoop()),
        session_listener_(this),
        session_connection_(CreateSessionConnection()),
        fake_surface_producer_(
            std::make_shared<FakeSurfaceProducer>(session_connection_->get())) {
  }
  ~GfxExternalViewEmbedderTest() override = default;

  async::TestLoop& loop() { return loop_; }

  FakeSession& fake_session() { return fake_session_; }

  std::shared_ptr<FakeSurfaceProducer> fake_surface_producer() {
    return fake_surface_producer_;
  }

  std::shared_ptr<GfxSessionConnection> session_connection() {
    return session_connection_;
  }

 private:
  // |fuchsia::ui::scenic::SessionListener|
  void OnScenicError(std::string error) override { FAIL(); }

  // |fuchsia::ui::scenic::SessionListener|
  void OnScenicEvent(std::vector<fuchsia::ui::scenic::Event> events) override {
    FAIL();
  }

  std::shared_ptr<GfxSessionConnection> CreateSessionConnection() {
    FML_CHECK(!fake_session_.is_bound());
    FML_CHECK(!session_listener_.is_bound());

    inspect::Node inspect_node =
        inspector_.GetRoot().CreateChild("GfxExternalViewEmbedderTest");

    auto [session, session_listener] =
        fake_session_.Bind(session_subloop_->dispatcher());
    session_listener_.Bind(std::move(session_listener));

    return std::make_shared<GfxSessionConnection>(
        GetCurrentTestName(), std::move(inspect_node), std::move(session),
        []() { FAIL(); }, [](auto...) {}, 1, fml::TimeDelta::Zero());
  }

  async::TestLoop loop_;  // Must come before FIDL bindings.
  std::unique_ptr<async::LoopInterface> session_subloop_;

  fidl::Binding<fuchsia::ui::scenic::SessionListener> session_listener_;

  inspect::Inspector inspector_;

  FakeSession fake_session_;

  std::shared_ptr<GfxSessionConnection> session_connection_;
  std::shared_ptr<FakeSurfaceProducer> fake_surface_producer_;
};

// Tests the trivial case where flutter does not present any content to scenic.
TEST_F(GfxExternalViewEmbedderTest, RootScene) {
  const std::string debug_name = GetCurrentTestName();
  auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
  auto view_ref_pair = scenic::ViewRefPair::New();
  fuchsia::ui::views::ViewRef view_ref;
  view_ref_pair.view_ref.Clone(&view_ref);

  GfxExternalViewEmbedder external_view_embedder(
      debug_name, std::move(view_token), std::move(view_ref_pair),
      session_connection(), fake_surface_producer());
  EXPECT_EQ(fake_session().debug_name(), "");
  EXPECT_THAT(fake_session().SceneGraph(), IsEmptySceneGraph());

  // Pump the loop; the contents of the initial `Present` should be processed.
  loop().RunUntilIdle();
  EXPECT_EQ(fake_session().debug_name(), debug_name);
  ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name,
                       view_holder_token, view_ref);

  // Fire the `OnFramePresented` event associated with the first `Present`, then
  // pump the loop.  The `OnFramePresented` event is resolved.
  //
  // The scene graph shouldn't change.
  fake_session().FireOnFramePresentedEvent(
      MakeFramePresentedInfoForOnePresent(0, 0));
  loop().RunUntilIdle();
  ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name,
                       view_holder_token, view_ref);
}

// Tests the case where flutter renders a single image.
TEST_F(GfxExternalViewEmbedderTest, SimpleScene) {
  const std::string debug_name = GetCurrentTestName();
  auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
  auto view_ref_pair = scenic::ViewRefPair::New();
  fuchsia::ui::views::ViewRef view_ref;
  view_ref_pair.view_ref.Clone(&view_ref);

  // Create the `GfxExternalViewEmbedder` and pump the message loop until
  // the initial scene graph is setup.
  GfxExternalViewEmbedder external_view_embedder(
      debug_name, std::move(view_token), std::move(view_ref_pair),
      session_connection(), fake_surface_producer());
  loop().RunUntilIdle();
  fake_session().FireOnFramePresentedEvent(
      MakeFramePresentedInfoForOnePresent(0, 0));
  loop().RunUntilIdle();
  ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name,
                       view_holder_token, view_ref);

  // Draw the scene.  The scene graph shouldn't change yet.
  const SkISize frame_size = SkISize::Make(512, 512);
  SkRect paint_region;
  DrawSimpleFrame(
      external_view_embedder, frame_size, 1.f,
      [&paint_region](SkCanvas* canvas) {
        const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(),
                                                canvas->imageInfo().height());
        SkPaint rect_paint;
        rect_paint.setColor(SK_ColorGREEN);

        paint_region = SkRect::MakeXYWH(
            canvas_size.width() / 4.f, canvas_size.height() / 2.f,
            canvas_size.width() / 32.f, canvas_size.height() / 32.f);

        canvas->drawRect(paint_region, rect_paint);
      });
  ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name,
                       view_holder_token, view_ref);

  // Pump the message loop.  The scene updates should propogate to Scenic.
  loop().RunUntilIdle();
  std::vector<FakeResource> scenic_layers =
      ExtractLayersFromSceneGraph(fake_session().SceneGraph());
  EXPECT_EQ(scenic_layers.size(), 1u);
  ExpectImageCompositorLayer(scenic_layers[0], frame_size,
                             /* flutter layer index = */ 0, {paint_region});
}

// Tests the case where flutter embeds a platform view on top of an image layer.
TEST_F(GfxExternalViewEmbedderTest, SceneWithOneView) {
  const std::string debug_name = GetCurrentTestName();
  auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
  auto view_ref_pair = scenic::ViewRefPair::New();
  fuchsia::ui::views::ViewRef view_ref;
  view_ref_pair.view_ref.Clone(&view_ref);

  // Create the `GfxExternalViewEmbedder` and pump the message loop until
  // the initial scene graph is setup.
  GfxExternalViewEmbedder external_view_embedder(
      debug_name, std::move(view_token), std::move(view_ref_pair),
      session_connection(), fake_surface_producer());
  loop().RunUntilIdle();
  fake_session().FireOnFramePresentedEvent(
      MakeFramePresentedInfoForOnePresent(0, 0));
  loop().RunUntilIdle();
  ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name,
                       view_holder_token, view_ref);

  // Create the view before drawing the scene.
  const SkSize child_view_size = SkSize::Make(256.f, 512.f);
  auto [child_view_token, child_view_holder_token] =
      scenic::ViewTokenPair::New();
  const uint32_t child_view_id = child_view_holder_token.value.get();
  flutter::EmbeddedViewParams child_view_params(SkMatrix::I(), child_view_size,
                                                flutter::MutatorsStack());
  external_view_embedder.CreateView(
      child_view_id, []() {}, [](scenic::ResourceId) {});

  // Draw the scene.  The scene graph shouldn't change yet.
  const SkISize frame_size = SkISize::Make(512, 512);

  SkRect main_surface_paint_region, overlay_paint_region;

  DrawFrameWithView(
      external_view_embedder, frame_size, 1.f, child_view_id, child_view_params,
      [&main_surface_paint_region](SkCanvas* canvas) {
        const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(),
                                                canvas->imageInfo().height());

        main_surface_paint_region = SkRect::MakeXYWH(
            canvas_size.width() / 4.f, canvas_size.width() / 2.f,
            canvas_size.width() / 32.f, canvas_size.height() / 32.f);

        SkPaint rect_paint;
        rect_paint.setColor(SK_ColorGREEN);
        canvas->drawRect(main_surface_paint_region, rect_paint);
      },
      [&overlay_paint_region](SkCanvas* canvas) {
        const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(),
                                                canvas->imageInfo().height());
        overlay_paint_region = SkRect::MakeXYWH(
            canvas_size.width() * 3.f / 4.f, canvas_size.height() / 2.f,
            canvas_size.width() / 32.f, canvas_size.height() / 32.f);

        SkPaint rect_paint;
        rect_paint.setColor(SK_ColorRED);
        canvas->drawRect(overlay_paint_region, rect_paint);
      });
  ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name,
                       view_holder_token, view_ref);

  // Pump the message loop.  The scene updates should propagate to Scenic.
  loop().RunUntilIdle();
  std::vector<FakeResource> scenic_layers =
      ExtractLayersFromSceneGraph(fake_session().SceneGraph());
  EXPECT_EQ(scenic_layers.size(), 3u);
  ExpectImageCompositorLayer(scenic_layers[0], frame_size,
                             /* flutter layer index = */ 0,
                             {main_surface_paint_region});
  ExpectViewCompositorLayer(scenic_layers[1], child_view_token,
                            child_view_params,
                            /* flutter layer index = */ 1);
  ExpectImageCompositorLayer(scenic_layers[2], frame_size,
                             /* flutter layer index = */ 1,
                             {overlay_paint_region});

  // Destroy the view.
  external_view_embedder.DestroyView(child_view_id, [](scenic::ResourceId) {});

  // Pump the message loop.
  loop().RunUntilIdle();
}

// Tests the case where flutter renders an image with two non-overlapping pieces
// of content. In this case, the embedder should report two separate hit regions
// to scenic.
TEST_F(GfxExternalViewEmbedderTest, SimpleSceneDisjointHitRegions) {
  const std::string debug_name = GetCurrentTestName();
  auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
  auto view_ref_pair = scenic::ViewRefPair::New();
  fuchsia::ui::views::ViewRef view_ref;
  view_ref_pair.view_ref.Clone(&view_ref);

  // Create the `GfxExternalViewEmbedder` and pump the message loop until
  // the initial scene graph is setup.
  GfxExternalViewEmbedder external_view_embedder(
      debug_name, std::move(view_token), std::move(view_ref_pair),
      session_connection(), fake_surface_producer());
  loop().RunUntilIdle();
  fake_session().FireOnFramePresentedEvent(
      MakeFramePresentedInfoForOnePresent(0, 0));
  loop().RunUntilIdle();
  ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name,
                       view_holder_token, view_ref);

  // Draw the scene.  The scene graph shouldn't change yet.
  SkRect paint_region_1, paint_region_2;
  const SkISize frame_size = SkISize::Make(512, 512);
  DrawSimpleFrame(
      external_view_embedder, frame_size, 1.f,
      [&paint_region_1, &paint_region_2](SkCanvas* canvas) {
        const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(),
                                                canvas->imageInfo().height());

        paint_region_1 = SkRect::MakeXYWH(
            canvas_size.width() / 4.f, canvas_size.height() / 2.f,
            canvas_size.width() / 32.f, canvas_size.height() / 32.f);

        SkPaint rect_paint;
        rect_paint.setColor(SK_ColorGREEN);
        canvas->drawRect(paint_region_1, rect_paint);

        paint_region_2 = SkRect::MakeXYWH(
            canvas_size.width() * 3.f / 4.f, canvas_size.height() / 2.f,
            canvas_size.width() / 32.f, canvas_size.height() / 32.f);

        rect_paint.setColor(SK_ColorRED);
        canvas->drawRect(paint_region_2, rect_paint);
      });
  ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name,
                       view_holder_token, view_ref);

  // Pump the message loop.  The scene updates should propogate to Scenic.
  loop().RunUntilIdle();
  std::vector<FakeResource> scenic_layers =
      ExtractLayersFromSceneGraph(fake_session().SceneGraph());
  EXPECT_EQ(scenic_layers.size(), 1u);
  ExpectImageCompositorLayer(scenic_layers[0], frame_size,
                             /* flutter layer index = */ 0,
                             {paint_region_1, paint_region_2});
}

// Tests the case where flutter renders an image with two overlapping pieces of
// content. In this case, the embedder should report a single joint hit region
// to scenic.
TEST_F(GfxExternalViewEmbedderTest, SimpleSceneOverlappingHitRegions) {
  const std::string debug_name = GetCurrentTestName();
  auto [view_token, view_holder_token] = scenic::ViewTokenPair::New();
  auto view_ref_pair = scenic::ViewRefPair::New();
  fuchsia::ui::views::ViewRef view_ref;
  view_ref_pair.view_ref.Clone(&view_ref);

  // Create the `GfxExternalViewEmbedder` and pump the message loop until
  // the initial scene graph is setup.
  GfxExternalViewEmbedder external_view_embedder(
      debug_name, std::move(view_token), std::move(view_ref_pair),
      session_connection(), fake_surface_producer());
  loop().RunUntilIdle();
  fake_session().FireOnFramePresentedEvent(
      MakeFramePresentedInfoForOnePresent(0, 0));
  loop().RunUntilIdle();
  ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name,
                       view_holder_token, view_ref);

  // Draw the scene.  The scene graph shouldn't change yet.
  SkRect joined_paint_region = SkRect::MakeEmpty();
  const SkISize frame_size = SkISize::Make(512, 512);
  DrawSimpleFrame(
      external_view_embedder, frame_size, 1.f,
      [&joined_paint_region](SkCanvas* canvas) {
        const SkSize canvas_size = SkSize::Make(canvas->imageInfo().width(),
                                                canvas->imageInfo().height());

        auto paint_region_1 = SkRect::MakeXYWH(
            canvas_size.width() / 4.f, canvas_size.height() / 4.f,
            canvas_size.width() / 2.f, canvas_size.height() / 2.f);
        SkPaint rect_paint;
        rect_paint.setColor(SK_ColorGREEN);
        canvas->drawRect(paint_region_1, rect_paint);

        auto paint_region_2 = SkRect::MakeXYWH(
            canvas_size.width() * 3.f / 8.f, canvas_size.height() / 4.f,
            canvas_size.width() / 2.f, canvas_size.height() / 2.f);
        rect_paint.setColor(SK_ColorRED);
        canvas->drawRect(paint_region_2, rect_paint);

        joined_paint_region.join(paint_region_1);
        joined_paint_region.join(paint_region_2);
      });
  ExpectRootSceneGraph(fake_session().SceneGraph(), debug_name,
                       view_holder_token, view_ref);

  EXPECT_EQ(joined_paint_region.x(), 128.f);
  EXPECT_EQ(joined_paint_region.y(), 128.f);
  EXPECT_EQ(joined_paint_region.width(), 320.f);
  EXPECT_EQ(joined_paint_region.height(), 256.f);
  // Pump the message loop.  The scene updates should propogate to Scenic.
  loop().RunUntilIdle();
  std::vector<FakeResource> scenic_layers =
      ExtractLayersFromSceneGraph(fake_session().SceneGraph());
  EXPECT_EQ(scenic_layers.size(), 1u);
  ExpectImageCompositorLayer(scenic_layers[0], frame_size,
                             /* flutter layer index = */ 0,
                             {joined_paint_region});
}

}  // namespace flutter_runner::testing
