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

#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 "gtest/gtest.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 MockSessionWrapper : public flutter::SessionWrapper {
 public:
  MockSessionWrapper(fuchsia::ui::scenic::SessionPtr session_ptr)
      : session_(std::move(session_ptr)) {}
  ~MockSessionWrapper() override = default;

  scenic::Session* get() override { return &session_; }
  void Present() override { session_.Flush(); }

 private:
  scenic::Session session_;
};

struct TestContext {
  // Session.
  fidl::InterfaceRequest<fuchsia::ui::scenic::SessionListener> listener_request;
  MockSession mock_session;
  std::unique_ptr<MockSessionWrapper> mock_session_wrapper;

  // SceneUpdateContext.
  std::shared_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 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->mock_session_wrapper =
      std::make_unique<MockSessionWrapper>(std::move(session_ptr));

  // Init SceneUpdateContext.
  context->scene_update_context = std::make_shared<SceneUpdateContext>(
      "fuchsia_layer_unittest", fuchsia::ui::views::ViewToken(),
      scenic::ViewRefPair::New(), *(context->mock_session_wrapper));

  // 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
      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_, nullptr); }

 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,
      /*bind_callback=*/[](scenic::ResourceId id) {},
      std::move(unused_view_holder_token1));
  // 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,
      /*bind_callback=*/[](scenic::ResourceId id) {},
      std::move(unused_view_holder_token2));
  // 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->mock_session_wrapper->Present();

  // 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,
      /*bind_callback=*/[](scenic::ResourceId id) {},
      std::move(unused_view_holder_token1));
  // 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->mock_session_wrapper->Present();

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