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

#include "gtest/gtest.h"

#include <fuchsia/ui/scenic/cpp/fidl.h>
#include <fuchsia/ui/scenic/cpp/fidl_test_base.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/default.h>
#include <lib/fidl/cpp/optional.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/ui/scenic/cpp/commands.h>
#include <lib/ui/scenic/cpp/id.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>

#include "flutter/flow/layers/child_scene_layer.h"
#include "flutter/flow/layers/container_layer.h"
#include "flutter/flow/layers/opacity_layer.h"
#include "flutter/flow/layers/physical_shape_layer.h"
#include "flutter/flow/layers/transform_layer.h"
#include "flutter/flow/view_holder.h"
#include "flutter/fml/platform/fuchsia/message_loop_fuchsia.h"
#include "flutter/fml/task_runner.h"

namespace flutter {
namespace testing {

using FuchsiaLayerTest = ::testing::Test;

class MockSession : public fuchsia::ui::scenic::testing::Session_TestBase {
 public:
  MockSession() : binding_(this) {}

  void NotImplemented_(const std::string& name) final {}

  void Bind(fidl::InterfaceRequest<::fuchsia::ui::scenic::Session> request,
            ::fuchsia::ui::scenic::SessionListenerPtr listener) {
    binding_.Bind(std::move(request));
    listener_ = std::move(listener);
  }

  static std::string Vec3ValueToString(fuchsia::ui::gfx::Vector3Value value) {
    return "{" + std::to_string(value.value.x) + ", " +
           std::to_string(value.value.y) + ", " +
           std::to_string(value.value.z) + "}";
  }

  static std::string QuaternionValueToString(
      fuchsia::ui::gfx::QuaternionValue value) {
    return "{" + std::to_string(value.value.x) + ", " +
           std::to_string(value.value.y) + ", " +
           std::to_string(value.value.z) + ", " +
           std::to_string(value.value.w) + "}";
  }

  static std::string GfxCreateResourceCmdToString(
      const fuchsia::ui::gfx::CreateResourceCmd& cmd) {
    std::string id = " id: " + std::to_string(cmd.id);
    switch (cmd.resource.Which()) {
      case fuchsia::ui::gfx::ResourceArgs::Tag::kRectangle:
        return "Rectangle" + id;
      case fuchsia::ui::gfx::ResourceArgs::Tag::kRoundedRectangle:
        return "RoundedRectangle" + id;
      case fuchsia::ui::gfx::ResourceArgs::Tag::kViewHolder:
        return "ViewHolder" + id;
      case fuchsia::ui::gfx::ResourceArgs::Tag::kOpacityNode:
        return "OpacityNode" + id;
      case fuchsia::ui::gfx::ResourceArgs::Tag::kEntityNode:
        return "EntityNode" + id;
      case fuchsia::ui::gfx::ResourceArgs::Tag::kShapeNode:
        return "ShapeNode" + id;
      case fuchsia::ui::gfx::ResourceArgs::Tag::kMaterial:
        return "Material" + id;
      case fuchsia::ui::gfx::ResourceArgs::Tag::kImage:
        return "Image" + id + ", memory_id: " +
               std::to_string(cmd.resource.image().memory_id) +
               ", memory_offset: " +
               std::to_string(cmd.resource.image().memory_offset);
      default:
        return "Unhandled CreateResource command" +
               std::to_string(cmd.resource.Which());
    }
  }

  static std::string GfxCmdToString(const fuchsia::ui::gfx::Command& cmd) {
    switch (cmd.Which()) {
      case fuchsia::ui::gfx::Command::Tag::kCreateResource:
        return "CreateResource: " +
               GfxCreateResourceCmdToString(cmd.create_resource());
      case fuchsia::ui::gfx::Command::Tag::kReleaseResource:
        return "ReleaseResource id: " +
               std::to_string(cmd.release_resource().id);
      case fuchsia::ui::gfx::Command::Tag::kAddChild:
        return "AddChild id: " + std::to_string(cmd.add_child().node_id) +
               " child_id: " + std::to_string(cmd.add_child().child_id);
      case fuchsia::ui::gfx::Command::Tag::kSetTranslation:
        return "SetTranslation id: " +
               std::to_string(cmd.set_translation().id) +
               " value: " + Vec3ValueToString(cmd.set_translation().value);
      case fuchsia::ui::gfx::Command::Tag::kSetScale:
        return "SetScale id: " + std::to_string(cmd.set_scale().id) +
               " value: " + Vec3ValueToString(cmd.set_scale().value);
      case fuchsia::ui::gfx::Command::Tag::kSetRotation:
        return "SetRotation id: " + std::to_string(cmd.set_rotation().id) +
               " value: " + QuaternionValueToString(cmd.set_rotation().value);
      case fuchsia::ui::gfx::Command::Tag::kSetOpacity:
        return "SetOpacity id: " + std::to_string(cmd.set_opacity().node_id) +
               ", opacity: " + std::to_string(cmd.set_opacity().opacity);
      case fuchsia::ui::gfx::Command::Tag::kSetColor:
        return "SetColor id: " + std::to_string(cmd.set_color().material_id) +
               ", rgba: (" + std::to_string(cmd.set_color().color.value.red) +
               ", " + std::to_string(cmd.set_color().color.value.green) + ", " +
               std::to_string(cmd.set_color().color.value.blue) + ", " +
               std::to_string(cmd.set_color().color.value.alpha) + ")";
      case fuchsia::ui::gfx::Command::Tag::kSetLabel:
        return "SetLabel id: " + std::to_string(cmd.set_label().id) + " " +
               cmd.set_label().label;
      case fuchsia::ui::gfx::Command::Tag::kSetHitTestBehavior:
        return "SetHitTestBehavior node_id: " +
               std::to_string(cmd.set_hit_test_behavior().node_id);
      case fuchsia::ui::gfx::Command::Tag::kSetClipPlanes:
        return "SetClipPlanes node_id: " +
               std::to_string(cmd.set_clip_planes().node_id);
      case fuchsia::ui::gfx::Command::Tag::kSetShape:
        return "SetShape node_id: " + std::to_string(cmd.set_shape().node_id) +
               ", shape_id: " + std::to_string(cmd.set_shape().shape_id);
      case fuchsia::ui::gfx::Command::Tag::kSetMaterial:
        return "SetMaterial node_id: " +
               std::to_string(cmd.set_material().node_id) + ", material_id: " +
               std::to_string(cmd.set_material().material_id);
      case fuchsia::ui::gfx::Command::Tag::kSetTexture:
        return "SetTexture material_id: " +
               std::to_string(cmd.set_texture().material_id) +
               ", texture_id: " + std::to_string(cmd.set_texture().texture_id);

      default:
        return "Unhandled gfx command" + std::to_string(cmd.Which());
    }
  }

  static std::string ScenicCmdToString(
      const fuchsia::ui::scenic::Command& cmd) {
    if (cmd.Which() != fuchsia::ui::scenic::Command::Tag::kGfx) {
      return "Unhandled non-gfx command: " + std::to_string(cmd.Which());
    }
    return GfxCmdToString(cmd.gfx());
  }

  // |fuchsia::ui::scenic::Session|
  void Enqueue(std::vector<fuchsia::ui::scenic::Command> cmds) override {
    for (const auto& cmd : cmds) {
      num_enqueued_commands_++;
      EXPECT_FALSE(expected_.empty())
          << "Received more commands than expected; command: <"
          << ScenicCmdToString(cmd)
          << ">, num_enqueued_commands: " << num_enqueued_commands_;
      if (!expected_.empty()) {
        EXPECT_TRUE(AreCommandsEqual(expected_.front(), cmd))
            << "actual command: <" << ScenicCmdToString(cmd)
            << ">, expected command: <" << ScenicCmdToString(expected_.front())
            << ">, num_enqueued_commands: " << num_enqueued_commands_;
        expected_.pop_front();
      }
    }
  }

  void SetExpectedCommands(std::vector<fuchsia::ui::gfx::Command> gfx_cmds) {
    std::deque<fuchsia::ui::scenic::Command> scenic_commands;
    for (auto it = gfx_cmds.begin(); it != gfx_cmds.end(); it++) {
      scenic_commands.push_back(scenic::NewCommand(std::move((*it))));
    }
    expected_ = std::move(scenic_commands);
    num_enqueued_commands_ = 0;
  }

  size_t num_enqueued_commands() { return num_enqueued_commands_; }

 private:
  static bool IsGfxCommand(const fuchsia::ui::scenic::Command& cmd,
                           fuchsia::ui::gfx::Command::Tag tag) {
    return cmd.Which() == fuchsia::ui::scenic::Command::Tag::kGfx &&
           cmd.gfx().Which() == tag;
  }

  static bool IsCreateResourceCommand(const fuchsia::ui::scenic::Command& cmd,
                                      fuchsia::ui::gfx::ResourceArgs::Tag tag) {
    return IsGfxCommand(cmd, fuchsia::ui::gfx::Command::Tag::kCreateResource) &&
           cmd.gfx().create_resource().resource.Which() == tag;
  }

  static bool AreCommandsEqual(const fuchsia::ui::scenic::Command& command1,
                               const fuchsia::ui::scenic::Command& command2) {
    // For CreateViewHolderCommand, just compare the id and ignore the
    // view_holder_token.
    if (IsCreateResourceCommand(
            command1, fuchsia::ui::gfx::ResourceArgs::Tag::kViewHolder)) {
      return IsCreateResourceCommand(
                 command2, fuchsia::ui::gfx::ResourceArgs::Tag::kViewHolder) &&
             command1.gfx().create_resource().id ==
                 command2.gfx().create_resource().id;
    }
    // For CreateImageCommand, just compare the id and memory_id.
    if (IsCreateResourceCommand(command1,
                                fuchsia::ui::gfx::ResourceArgs::Tag::kImage)) {
      return IsCreateResourceCommand(
                 command2, fuchsia::ui::gfx::ResourceArgs::Tag::kImage) &&
             command1.gfx().create_resource().id ==
                 command2.gfx().create_resource().id &&
             command1.gfx().create_resource().resource.image().memory_id ==
                 command2.gfx().create_resource().resource.image().memory_id;
    }
    // For SetHitTestBehaviorCommand, just compare the node_id.
    if (IsGfxCommand(command1,
                     fuchsia::ui::gfx::Command::Tag::kSetHitTestBehavior)) {
      return IsGfxCommand(
                 command2,
                 fuchsia::ui::gfx::Command::Tag::kSetHitTestBehavior) &&
             command1.gfx().set_hit_test_behavior().node_id ==
                 command2.gfx().set_hit_test_behavior().node_id;
    }
    // For SetHitTestBehaviorCommand, just compare the node_id.
    if (IsGfxCommand(command1,
                     fuchsia::ui::gfx::Command::Tag::kSetClipPlanes)) {
      return IsGfxCommand(command2,
                          fuchsia::ui::gfx::Command::Tag::kSetClipPlanes) &&
             command1.gfx().set_clip_planes().node_id ==
                 command2.gfx().set_clip_planes().node_id;
    }
    return fidl::Equals(command1, command2);
  }

  std::deque<fuchsia::ui::scenic::Command> expected_;
  size_t num_enqueued_commands_ = 0;
  fidl::Binding<fuchsia::ui::scenic::Session> binding_;
  fuchsia::ui::scenic::SessionListenerPtr listener_;
};

class MockSurfaceProducerSurface
    : public SceneUpdateContext::SurfaceProducerSurface {
 public:
  MockSurfaceProducerSurface(scenic::Session* session, const SkISize& size)
      : image_(session, 0, 0, {}), size_(size) {}

  size_t AdvanceAndGetAge() override { return 0; }

  bool FlushSessionAcquireAndReleaseEvents() override { return false; }

  bool IsValid() const override { return false; }

  SkISize GetSize() const override { return size_; }

  void SignalWritesFinished(
      const std::function<void(void)>& on_writes_committed) override {}

  scenic::Image* GetImage() override { return &image_; };

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

 private:
  scenic::Image image_;
  SkISize size_;
};

class MockSurfaceProducer : public SceneUpdateContext::SurfaceProducer {
 public:
  MockSurfaceProducer(scenic::Session* session) : session_(session) {}
  std::unique_ptr<SceneUpdateContext::SurfaceProducerSurface> ProduceSurface(
      const SkISize& size,
      const LayerRasterCacheKey& layer_key,
      std::unique_ptr<scenic::EntityNode> entity_node) override {
    return std::make_unique<MockSurfaceProducerSurface>(session_, size);
  }

  // Query a retained entity node (owned by a retained surface) for retained
  // rendering.
  bool HasRetainedNode(const LayerRasterCacheKey& key) const override {
    return false;
  }

  scenic::EntityNode* GetRetainedNode(const LayerRasterCacheKey& key) override {
    return nullptr;
  }

  void SubmitSurface(std::unique_ptr<SceneUpdateContext::SurfaceProducerSurface>
                         surface) override {}

 private:
  scenic::Session* session_;
};

struct TestContext {
  // Message loop.
  fml::RefPtr<fml::MessageLoopFuchsia> loop;
  fml::RefPtr<fml::TaskRunner> task_runner;

  // Session.
  MockSession mock_session;
  fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener> listener_request;
  std::unique_ptr<scenic::Session> session;

  // SceneUpdateContext.
  std::unique_ptr<MockSurfaceProducer> mock_surface_producer;
  std::unique_ptr<SceneUpdateContext> scene_update_context;

  // PrerollContext.
  MutatorsStack unused_stack;
  const Stopwatch unused_stopwatch;
  TextureRegistry unused_texture_registry;
  std::unique_ptr<PrerollContext> preroll_context;
};

std::unique_ptr<TestContext> InitTest() {
  std::unique_ptr<TestContext> context = std::make_unique<TestContext>();

  // Init message loop.
  context->loop = fml::MakeRefCounted<fml::MessageLoopFuchsia>();
  context->task_runner = fml::MakeRefCounted<fml::TaskRunner>(context->loop);

  // Init Session.
  fuchsia::ui::scenic::SessionPtr session_ptr;
  fuchsia::ui::scenic::SessionListenerPtr listener;
  context->listener_request = listener.NewRequest();
  context->mock_session.Bind(session_ptr.NewRequest(), std::move(listener));
  context->session = std::make_unique<scenic::Session>(std::move(session_ptr));

  // Init SceneUpdateContext.
  context->mock_surface_producer =
      std::make_unique<MockSurfaceProducer>(context->session.get());
  context->scene_update_context = std::make_unique<SceneUpdateContext>(
      context->session.get(), context->mock_surface_producer.get());
  context->scene_update_context->set_metrics(
      fidl::MakeOptional(fuchsia::ui::gfx::Metrics{1.f, 1.f, 1.f}));

  // Init PrerollContext.
  context->preroll_context = std::unique_ptr<PrerollContext>(new PrerollContext{
      nullptr,                    // raster_cache (don't consult the cache)
      nullptr,                    // gr_context  (used for the raster cache)
      nullptr,                    // external view embedder
      context->unused_stack,      // mutator stack
      nullptr,                    // SkColorSpace* dst_color_space
      kGiantRect,                 // SkRect cull_rect
      false,                      // layer reads from surface
      context->unused_stopwatch,  // frame time (dont care)
      context->unused_stopwatch,  // engine time (dont care)
      context->unused_texture_registry,  // texture registry (not
                                         // supported)
      false,                             // checkerboard_offscreen_layers
      100.f,                             // maximum depth allowed for rendering
      1.f                                // ratio between logical and physical
  });

  return context;
}

zx_koid_t GetChildLayerId() {
  static zx_koid_t sChildLayerId = 17324;
  return sChildLayerId++;
}

class AutoDestroyChildLayerId {
 public:
  AutoDestroyChildLayerId(zx_koid_t id) : id_(id) {}
  ~AutoDestroyChildLayerId() { ViewHolder::Destroy(id_); }

 private:
  zx_koid_t id_;
};

// Create a hierarchy with PhysicalShapeLayers and ChildSceneLayers, and
// inspect the commands sent to Scenic.
//
//
// What we expect:
//
// The Scenic elevations of the PhysicalShapeLayers are monotically
// increasing, even though the elevations we gave them when creating them are
// decreasing. The two should not have any correlation; we're merely mirror
// the paint order using Scenic elevation.
//
// PhysicalShapeLayers created before/below a ChildView do not get their own
// node; PhysicalShapeLayers created afterward do.
//
// Nested PhysicalShapeLayers are collapsed.
//
// This test has been temporarily disabled: fxb/52028
TEST_F(FuchsiaLayerTest, DISABLED_PhysicalShapeLayersAndChildSceneLayers) {
  auto test_context = InitTest();

  // Root.
  auto root = std::make_shared<ContainerLayer>();
  SkPath path;
  path.addRect(SkRect::MakeWH(10.f, 10.f));

  // Child #1: PhysicalShapeLayer.
  auto physical_shape1 = std::make_shared<PhysicalShapeLayer>(
      /*color=*/SK_ColorCYAN,
      /*shadow_color=*/SK_ColorBLACK,
      /*elevation*/ 23.f, path, Clip::antiAlias);
  root->Add(physical_shape1);

  // Child #2: ChildSceneLayer.
  const zx_koid_t kChildLayerId1 = GetChildLayerId();
  auto [unused_view_token1, unused_view_holder_token1] =
      scenic::ViewTokenPair::New();
  ViewHolder::Create(kChildLayerId1, test_context->task_runner,
                     std::move(unused_view_holder_token1),
                     /*bind_callback=*/[](scenic::ResourceId id) {});
  // Will destroy only when we go out of scope (i.e. end of the test).
  AutoDestroyChildLayerId auto_destroy1(kChildLayerId1);
  auto child_view1 = std::make_shared<ChildSceneLayer>(
      kChildLayerId1, SkPoint::Make(1, 1), SkSize::Make(10, 10),
      /*hit_testable=*/false);
  root->Add(child_view1);

  // Child #3: PhysicalShapeLayer
  auto physical_shape2 = std::make_shared<PhysicalShapeLayer>(
      /*color=*/SK_ColorCYAN,
      /*shadow_color=*/SK_ColorBLACK,
      /*elevation*/ 21.f, path, Clip::antiAlias);
  root->Add(physical_shape2);

  // Grandchild (child of #3): PhysicalShapeLayer
  auto physical_shape3 = std::make_shared<PhysicalShapeLayer>(
      /*color=*/SK_ColorCYAN,
      /*shadow_color=*/SK_ColorBLACK,
      /*elevation*/ 19.f, path, Clip::antiAlias);
  physical_shape2->Add(physical_shape3);

  // Child #4: ChildSceneLayer
  const zx_koid_t kChildLayerId2 = GetChildLayerId();
  auto [unused_view_token2, unused_view_holder_token2] =
      scenic::ViewTokenPair::New();
  ViewHolder::Create(kChildLayerId2, test_context->task_runner,
                     std::move(unused_view_holder_token2),
                     /*bind_callback=*/[](scenic::ResourceId id) {});
  // Will destroy only when we go out of scope (i.e. end of the test).
  AutoDestroyChildLayerId auto_destroy2(kChildLayerId2);
  auto child_view2 = std::make_shared<ChildSceneLayer>(
      kChildLayerId2, SkPoint::Make(1, 1), SkSize::Make(10, 10),
      /*hit_testable=*/false);
  root->Add(child_view2);

  // Child #5: PhysicalShapeLayer
  auto physical_shape4 = std::make_shared<PhysicalShapeLayer>(
      /*color=*/SK_ColorCYAN,
      /*shadow_color=*/SK_ColorBLACK,
      /*elevation*/ 17.f, path, Clip::antiAlias);
  root->Add(physical_shape4);

  // Preroll.
  root->Preroll(test_context->preroll_context.get(), SkMatrix());

  // Create another frame to be the "real" root. Required because
  // UpdateScene() traversal expects there to already be a top node.
  SceneUpdateContext::Frame frame(*(test_context->scene_update_context),
                                  SkRRect::MakeRect(SkRect::MakeWH(100, 100)),
                                  SK_ColorTRANSPARENT, SK_AlphaOPAQUE,
                                  "fuchsia test root");

  // Submit the list of command we will expect Scenic to see.
  //
  // Some things we expect:
  //
  // The Scenic elevations of the PhysicalShapeLayers are monotically
  // increasing, even though the elevations we gave them when creating them are
  // decreasing. The two should not have any correlation; we're merely mirror
  // the paint order using Scenic elevation.
  //
  // PhysicalShapeLayers created before/below a ChildView do not get their own
  // node; PhysicalShapeLayers created afterward do.
  //
  // Nested PhysicalShapeLayers are collapsed.

  std::vector<fuchsia::ui::gfx::Command> expected;

  //
  // Test root.
  //
  expected.push_back(scenic::NewCreateEntityNodeCmd(/*id=*/1));
  expected.push_back(scenic::NewCreateOpacityNodeCmdHACK(/*id=*/2));
  expected.push_back(scenic::NewSetLabelCmd(/*id=*/1, "fuchsia test root"));
  expected.push_back(scenic::NewSetTranslationCmd(/*id=*/1, {0, 0}));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/1, /*child_id=*/2));
  expected.push_back(scenic::NewSetOpacityCmd(/*id=*/2, kOneMinusEpsilon));

  //
  // Child #1: PhysicalShapeLayer
  //
  // Expect no new commands! Should be composited into base layer.

  //
  // Child #2: ChildSceneLayer.
  //
  expected.push_back(scenic::NewCreateEntityNodeCmd(/*id=*/3));
  expected.push_back(scenic::NewCreateOpacityNodeCmdHACK(/*id=*/4));
  auto [view_token1, view_holder_token1] = scenic::ViewTokenPair::New();
  expected.push_back(scenic::NewCreateViewHolderCmd(
      /*id=*/5, std::move(view_holder_token1), ""));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/4, /*child_id=*/3));
  expected.push_back(scenic::NewSetLabelCmd(/*id=*/4, "flutter::ViewHolder"));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/3, /*child_id=*/5));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/2, /*child_id=*/4));
  expected.push_back(scenic::NewSetOpacityCmd(/*id=*/4, 1.f));
  expected.push_back(scenic::NewSetTranslationCmd(/*id=*/3, {1, 1, -0.1}));
  expected.push_back(scenic::NewSetHitTestBehaviorCmd(
      /*id=*/3, /*ignored*/ fuchsia::ui::gfx::HitTestBehavior::kSuppress));

  //
  // Child #3: PhysicalShapeLayer
  //
  expected.push_back(scenic::NewCreateEntityNodeCmd(/*id=*/6));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/2, /*child_id=*/6));
  expected.push_back(scenic::NewCreateOpacityNodeCmdHACK(/*id=*/7));
  expected.push_back(
      scenic::NewSetLabelCmd(/*id=*/6, "flutter::PhysicalShapeLayer"));
  expected.push_back(scenic::NewSetTranslationCmd(
      /*id=*/6, {0, 0, -kScenicZElevationBetweenLayers}));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/6, /*child_id=*/7));
  expected.push_back(scenic::NewSetOpacityCmd(/*id=*/7, kOneMinusEpsilon));
  expected.push_back(scenic::NewSetClipPlanesCmd(/*id=*/6, /*ignored*/ {}));
  expected.push_back(scenic::NewCreateShapeNodeCmd(/*id=*/8));
  expected.push_back(scenic::NewCreateRectangleCmd(
      /*id=*/9, /*width=*/10, /*height=*/10));
  expected.push_back(scenic::NewSetShapeCmd(/*id=*/8, /*shape_id=*/9));
  expected.push_back(scenic::NewSetTranslationCmd(/*id=*/8, {5, 5, 0}));
  expected.push_back(scenic::NewCreateMaterialCmd(/*id=*/10));
  expected.push_back(scenic::NewSetMaterialCmd(/*id=*/8, /*material_id=*/10));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/6, /*child_id=*/8));

  expected.push_back(scenic::NewCreateImageCmd(/*id=*/11, 0, 0, {}));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/6));
  expected.push_back(scenic::NewSetColorCmd(/*id=*/10, /*r*/ 255, /*g*/ 255,
                                            /*b*/ 255, /*a*/ 255));
  expected.push_back(
      scenic::NewSetTextureCmd(/*material_id=*/10, /*texture_id=*/11));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/10));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/9));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/8));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/7));

  //
  // Grandchild (child of #3): PhysicalShapeLayer
  //
  // Expect no new commands! Should be composited into parent.

  //
  // Child #4: ChildSceneLayer
  //
  expected.push_back(scenic::NewCreateEntityNodeCmd(/*id=*/12));
  expected.push_back(scenic::NewCreateOpacityNodeCmdHACK(/*id=*/13));
  auto [view_token2, view_holder_token2] = scenic::ViewTokenPair::New();
  expected.push_back(scenic::NewCreateViewHolderCmd(
      /*id=*/14, std::move(view_holder_token2), ""));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/13, /*child_id=*/12));
  expected.push_back(scenic::NewSetLabelCmd(/*id=*/13, "flutter::ViewHolder"));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/12, /*child_id=*/14));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/2, /*child_id=*/13));
  expected.push_back(scenic::NewSetOpacityCmd(/*id=*/13, 1.f));
  expected.push_back(scenic::NewSetTranslationCmd(/*id=*/12, {1, 1, -0.1}));
  expected.push_back(scenic::NewSetHitTestBehaviorCmd(
      /*id=*/12, /*ignored*/ fuchsia::ui::gfx::HitTestBehavior::kSuppress));

  //
  // Child #5: PhysicalShapeLayer
  //
  expected.push_back(scenic::NewCreateEntityNodeCmd(/*id=*/15));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/2, /*child_id=*/15));
  expected.push_back(scenic::NewCreateOpacityNodeCmdHACK(/*id=*/16));
  expected.push_back(
      scenic::NewSetLabelCmd(/*id=*/15, "flutter::PhysicalShapeLayer"));
  expected.push_back(scenic::NewSetTranslationCmd(
      /*id=*/15, {0, 0, -2 * kScenicZElevationBetweenLayers}));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/15, /*child_id=*/16));
  expected.push_back(scenic::NewSetOpacityCmd(/*id=*/16, kOneMinusEpsilon));
  expected.push_back(scenic::NewSetClipPlanesCmd(/*id=*/15, /*ignored*/ {}));
  expected.push_back(scenic::NewCreateShapeNodeCmd(/*id=*/17));
  expected.push_back(scenic::NewCreateRectangleCmd(
      /*id=*/18, /*width=*/10, /*height=*/10));
  expected.push_back(scenic::NewSetShapeCmd(/*id=*/17, /*shape_id=*/18));
  expected.push_back(scenic::NewSetTranslationCmd(/*id=*/17, {5, 5, 0}));
  expected.push_back(scenic::NewCreateMaterialCmd(/*id=*/19));
  expected.push_back(scenic::NewSetMaterialCmd(/*id=*/17, /*material_id=*/19));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/15, /*child_id=*/17));

  expected.push_back(scenic::NewCreateImageCmd(/*id=*/20, 0, 0, {}));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/15));
  expected.push_back(scenic::NewSetColorCmd(/*id=*/19, /*r*/ 255, /*g*/ 255,
                                            /*b*/ 255, /*a*/ 255));
  expected.push_back(
      scenic::NewSetTextureCmd(/*material_id=*/19, /*texture_id=*/20));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/19));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/18));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/17));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/16));

  test_context->mock_session.SetExpectedCommands(std::move(expected));

  // Finally, UpdateScene(). The MockSession will check the emitted commands
  // against the list above.
  root->UpdateScene(*(test_context->scene_update_context));

  test_context->session->Flush();

  // Run loop until idle, so that the Session receives and processes
  // its method calls.
  async_loop_run_until_idle(
      async_loop_from_dispatcher(async_get_default_dispatcher()));

  // Ensure we saw enough commands.
  EXPECT_EQ(72u, test_context->mock_session.num_enqueued_commands());
}

// Create a hierarchy with OpacityLayers, TransformLayer, PhysicalShapeLayers
// and ChildSceneLayers, and inspect the commands sent to Scenic.
//
// We are interested in verifying that the opacity values of children are
// correct, and the transform values as well.
//
// This test has been temporarily disabled: fxb/52028
TEST_F(FuchsiaLayerTest, DISABLED_OpacityAndTransformLayer) {
  auto test_context = InitTest();

  // Root.
  auto root = std::make_shared<ContainerLayer>();
  SkPath path;
  path.addRect(SkRect::MakeWH(10.f, 10.f));

  // OpacityLayer #1
  auto opacity_layer1 =
      std::make_shared<OpacityLayer>(127, SkPoint::Make(0, 0));
  root->Add(opacity_layer1);

  // OpacityLayer #2
  auto opacity_layer2 =
      std::make_shared<OpacityLayer>(127, SkPoint::Make(0, 0));
  opacity_layer1->Add(opacity_layer2);

  // TransformLayer
  SkMatrix translate_and_scale;
  translate_and_scale.setScaleTranslate(1.1f, 1.1f, 2.f, 2.f);
  auto transform_layer = std::make_shared<TransformLayer>(translate_and_scale);
  opacity_layer2->Add(transform_layer);

  // TransformLayer Child #1: ChildSceneLayer.
  const zx_koid_t kChildLayerId1 = GetChildLayerId();
  auto [unused_view_token1, unused_view_holder_token1] =
      scenic::ViewTokenPair::New();

  ViewHolder::Create(kChildLayerId1, test_context->task_runner,
                     std::move(unused_view_holder_token1),
                     /*bind_callback=*/[](scenic::ResourceId id) {});
  // Will destroy only when we go out of scope (i.e. end of the test).
  AutoDestroyChildLayerId auto_destroy1(kChildLayerId1);
  auto child_view1 = std::make_shared<ChildSceneLayer>(
      kChildLayerId1, SkPoint::Make(1, 1), SkSize::Make(10, 10),
      /*hit_testable=*/false);
  transform_layer->Add(child_view1);

  // TransformLayer Child #2: PhysicalShapeLayer.
  auto physical_shape1 = std::make_shared<PhysicalShapeLayer>(
      /*color=*/SK_ColorCYAN,
      /*shadow_color=*/SK_ColorBLACK,
      /*elevation*/ 23.f, path, Clip::antiAlias);
  transform_layer->Add(physical_shape1);

  // Preroll.
  root->Preroll(test_context->preroll_context.get(), SkMatrix());

  // Create another frame to be the "real" root. Required because
  // UpdateScene() traversal expects there to already be a top node.
  SceneUpdateContext::Frame frame(*(test_context->scene_update_context),
                                  SkRRect::MakeRect(SkRect::MakeWH(100, 100)),
                                  SK_ColorTRANSPARENT, SK_AlphaOPAQUE,
                                  "fuchsia test root");

  // Submit the list of command we will expect Scenic to see.
  //
  // We are interested in verifying that the opacity values of children are
  // correct.

  std::vector<fuchsia::ui::gfx::Command> expected;

  //
  // Test root.
  //
  expected.push_back(scenic::NewCreateEntityNodeCmd(/*id=*/1));
  expected.push_back(scenic::NewCreateOpacityNodeCmdHACK(/*id=*/2));
  expected.push_back(scenic::NewSetLabelCmd(/*id=*/1, "fuchsia test root"));
  expected.push_back(scenic::NewSetTranslationCmd(/*id=*/1, {0, 0, 0}));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/1, /*child_id=*/2));
  expected.push_back(scenic::NewSetOpacityCmd(/*id=*/2, kOneMinusEpsilon));

  //
  // OpacityLayer #1
  //
  // Expect no new commands for this.

  //
  // OpacityLayer #2
  //
  // Expect no new commands for this.

  //
  // TransformLayer
  //
  //
  expected.push_back(scenic::NewCreateEntityNodeCmd(/*id=*/3));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/2, /*child_id=*/3));
  expected.push_back(scenic::NewSetLabelCmd(/*id=*/3, "flutter::Transform"));
  expected.push_back(scenic::NewSetTranslationCmd(/*id=*/3, {2.f, 2.f, 0.f}));
  expected.push_back(scenic::NewSetScaleCmd(/*id=*/3, {1.1f, 1.1f, 1.f}));
  expected.push_back(scenic::NewSetRotationCmd(/*id=*/3, {0.f, 0.f, 0.f, 1.f}));

  //
  // TransformLayer Child #1: ChildSceneLayer.
  //
  expected.push_back(scenic::NewCreateEntityNodeCmd(/*id=*/4));
  expected.push_back(scenic::NewCreateOpacityNodeCmdHACK(/*id=*/5));
  auto [view_token1, view_holder_token1] = scenic::ViewTokenPair::New();
  expected.push_back(scenic::NewCreateViewHolderCmd(
      /*id=*/6, std::move(view_holder_token1), ""));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/5, /*child_id=*/4));
  expected.push_back(scenic::NewSetLabelCmd(/*id=*/5, "flutter::ViewHolder"));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/4, /*child_id=*/6));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/3, /*child_id=*/5));

  // Check opacity value. Extra rounding required because we pass alpha as
  // a uint/SkAlpha to SceneUpdateContext::Frame.
  float opacity1 = kOneMinusEpsilon * (127 / 255.f) * (127 / 255.f);
  opacity1 = SkScalarRoundToInt(opacity1 * 255) / 255.f;
  expected.push_back(scenic::NewSetOpacityCmd(/*id=*/5, opacity1));
  expected.push_back(scenic::NewSetTranslationCmd(/*id=*/4, {1, 1, -0.1}));
  expected.push_back(scenic::NewSetHitTestBehaviorCmd(
      /*id=*/4, /*ignored*/ fuchsia::ui::gfx::HitTestBehavior::kSuppress));

  //
  // TransformLayer Child #2: PhysicalShapeLayer
  //
  expected.push_back(scenic::NewCreateEntityNodeCmd(/*id=*/7));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/3, /*child_id=*/7));
  expected.push_back(scenic::NewCreateOpacityNodeCmdHACK(/*id=*/8));
  expected.push_back(
      scenic::NewSetLabelCmd(/*id=*/7, "flutter::PhysicalShapeLayer"));
  expected.push_back(scenic::NewSetTranslationCmd(
      /*id=*/7, {0, 0, -kScenicZElevationBetweenLayers}));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/7, /*child_id=*/8));

  // Check opacity value. Extra rounding required because we pass alpha as
  // a uint/SkAlpha to SceneUpdateContext::Frame.
  float opacity2 = kOneMinusEpsilon * (127 / 255.f) * (127 / 255.f);
  opacity2 = SkScalarRoundToInt(opacity2 * 255) / 255.f;
  expected.push_back(scenic::NewSetOpacityCmd(/*id=*/8, opacity2));
  expected.push_back(scenic::NewSetClipPlanesCmd(/*id=*/7, /*ignored*/ {}));
  expected.push_back(scenic::NewCreateShapeNodeCmd(/*id=*/9));
  expected.push_back(scenic::NewCreateRectangleCmd(
      /*id=*/10, /*width=*/10, /*height=*/10));
  expected.push_back(scenic::NewSetShapeCmd(/*id=*/9, /*shape_id=*/10));
  expected.push_back(scenic::NewSetTranslationCmd(/*id=*/9, {5, 5, 0}));
  expected.push_back(scenic::NewCreateMaterialCmd(/*id=*/11));
  expected.push_back(scenic::NewSetMaterialCmd(/*id=*/9,
                                               /*material_id=*/11));
  expected.push_back(scenic::NewAddChildCmd(/*id=*/7,
                                            /*child_id=*/9));

  expected.push_back(scenic::NewCreateImageCmd(/*id=*/12, 0, 0, {}));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/7));
  expected.push_back(scenic::NewSetColorCmd(/*id=*/11, /*r*/ 255,
                                            /*g*/ 255,
                                            /*b*/ 255, /*a*/ 63));
  expected.push_back(
      scenic::NewSetTextureCmd(/*material_id=*/11, /*texture_id=*/12));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/11));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/10));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/9));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/8));
  expected.push_back(scenic::NewReleaseResourceCmd(/*id=*/3));

  test_context->mock_session.SetExpectedCommands(std::move(expected));

  // Finally, UpdateScene(). The MockSession will check the emitted
  // commands against the list above.
  root->UpdateScene(*(test_context->scene_update_context));

  test_context->session->Flush();

  // Run loop until idle, so that the Session receives and processes
  // its method calls.
  async_loop_run_until_idle(
      async_loop_from_dispatcher(async_get_default_dispatcher()));

  // Ensure we saw enough commands.
  EXPECT_EQ(46u, test_context->mock_session.num_enqueued_commands());
}

}  // namespace testing
}  // namespace flutter
