// 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 "flatland_external_view_embedder.h"
#include <algorithm>
#include <cstdint>

#include "flutter/fml/trace_event.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace flutter_runner {
namespace {

// Since the flatland hit-region can be transformed (rotated, scaled or
// translated), we must ensure that the size of the hit-region will not cause
// overflows on operations (like FLT_MAX would).
constexpr float kMaxHitRegionSize = 1'000'000.f;

void AttachClipTransformChild(
    FlatlandConnection* flatland,
    FlatlandExternalViewEmbedder::ClipTransform* parent_clip_transform,
    const fuchsia::ui::composition::TransformId& child_transform_id) {
  flatland->flatland()->AddChild(parent_clip_transform->transform_id,
                                 child_transform_id);
  parent_clip_transform->children.push_back(child_transform_id);
}

void DetachClipTransformChildren(
    FlatlandConnection* flatland,
    FlatlandExternalViewEmbedder::ClipTransform* clip_transform) {
  for (auto& child : clip_transform->children) {
    flatland->flatland()->RemoveChild(clip_transform->transform_id, child);
  }
  clip_transform->children.clear();
}

}  // namespace

FlatlandExternalViewEmbedder::FlatlandExternalViewEmbedder(
    fuchsia::ui::views::ViewCreationToken view_creation_token,
    fuchsia::ui::views::ViewIdentityOnCreation view_identity,
    fuchsia::ui::composition::ViewBoundProtocols view_protocols,
    fidl::InterfaceRequest<fuchsia::ui::composition::ParentViewportWatcher>
        parent_viewport_watcher_request,
    std::shared_ptr<FlatlandConnection> flatland,
    std::shared_ptr<SurfaceProducer> surface_producer,
    bool intercept_all_input)
    : flatland_(flatland), surface_producer_(surface_producer) {
  flatland_->flatland()->CreateView2(
      std::move(view_creation_token), std::move(view_identity),
      std::move(view_protocols), std::move(parent_viewport_watcher_request));

  root_transform_id_ = flatland_->NextTransformId();
  flatland_->flatland()->CreateTransform(root_transform_id_);
  flatland_->flatland()->SetRootTransform(root_transform_id_);

  if (intercept_all_input) {
    input_interceptor_transform_ = flatland_->NextTransformId();
    flatland_->flatland()->CreateTransform(*input_interceptor_transform_);

    flatland_->flatland()->AddChild(root_transform_id_,
                                    *input_interceptor_transform_);
    child_transforms_.emplace_back(*input_interceptor_transform_);

    // Attach full-screen hit testing shield. Note that since the hit-region
    // may be transformed (translated, rotated), we do not want to set
    // width/height to FLT_MAX. This will cause a numeric overflow.
    flatland_->flatland()->SetHitRegions(
        *input_interceptor_transform_,
        {{{0, 0, kMaxHitRegionSize, kMaxHitRegionSize},
          fuchsia::ui::composition::HitTestInteraction::
              SEMANTICALLY_INVISIBLE}});
  }
}

FlatlandExternalViewEmbedder::~FlatlandExternalViewEmbedder() = default;

SkCanvas* FlatlandExternalViewEmbedder::GetRootCanvas() {
  auto found = frame_layers_.find(kRootLayerId);
  if (found == frame_layers_.end()) {
    FML_LOG(WARNING)
        << "No root canvas could be found. This is extremely unlikely and "
           "indicates that the external view embedder did not receive the "
           "notification to begin the frame.";
    return nullptr;
  }

  return found->second.canvas_spy->GetSpyingCanvas();
}

std::vector<SkCanvas*> FlatlandExternalViewEmbedder::GetCurrentCanvases() {
  std::vector<SkCanvas*> canvases;
  for (const auto& layer : frame_layers_) {
    // This method (for legacy reasons) expects non-root current canvases.
    if (layer.first.has_value()) {
      canvases.push_back(layer.second.canvas_spy->GetSpyingCanvas());
    }
  }
  return canvases;
}

std::vector<flutter::DisplayListBuilder*>
FlatlandExternalViewEmbedder::GetCurrentBuilders() {
  return std::vector<flutter::DisplayListBuilder*>();
}

void FlatlandExternalViewEmbedder::PrerollCompositeEmbeddedView(
    int view_id,
    std::unique_ptr<flutter::EmbeddedViewParams> params) {
  zx_handle_t handle = static_cast<zx_handle_t>(view_id);
  FML_CHECK(frame_layers_.count(handle) == 0);

  frame_layers_.emplace(std::make_pair(
      EmbedderLayerId{handle},
      EmbedderLayer(frame_size_, *params, flutter::RTreeFactory())));
  frame_composition_order_.push_back(handle);
}

flutter::EmbedderPaintContext
FlatlandExternalViewEmbedder::CompositeEmbeddedView(int view_id) {
  zx_handle_t handle = static_cast<zx_handle_t>(view_id);
  auto found = frame_layers_.find(handle);
  FML_CHECK(found != frame_layers_.end());

  return {found->second.canvas_spy->GetSpyingCanvas(), nullptr};
}

flutter::PostPrerollResult FlatlandExternalViewEmbedder::PostPrerollAction(
    fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
  return flutter::PostPrerollResult::kSuccess;
}

void FlatlandExternalViewEmbedder::BeginFrame(
    SkISize frame_size,
    GrDirectContext* context,
    double device_pixel_ratio,
    fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
  TRACE_EVENT0("flutter", "FlatlandExternalViewEmbedder::BeginFrame");

  // Reset for new frame.
  Reset();
  frame_size_ = frame_size;
  frame_dpr_ = device_pixel_ratio;

  // Create the root layer.
  frame_layers_.emplace(std::make_pair(
      kRootLayerId,
      EmbedderLayer(frame_size, std::nullopt, flutter::RTreeFactory())));
  frame_composition_order_.push_back(kRootLayerId);
}

void FlatlandExternalViewEmbedder::EndFrame(
    bool should_resubmit_frame,
    fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger) {
  TRACE_EVENT0("flutter", "FlatlandExternalViewEmbedder::EndFrame");
}

void FlatlandExternalViewEmbedder::SubmitFrame(
    GrDirectContext* context,
    std::unique_ptr<flutter::SurfaceFrame> frame) {
  TRACE_EVENT0("flutter", "FlatlandExternalViewEmbedder::SubmitFrame");
  std::vector<std::unique_ptr<SurfaceProducerSurface>> frame_surfaces;
  std::unordered_map<EmbedderLayerId, size_t> frame_surface_indices;

  // Create surfaces for the frame and associate them with layer IDs.
  {
    TRACE_EVENT0("flutter", "CreateSurfaces");

    for (const auto& layer : frame_layers_) {
      if (!layer.second.canvas_spy->DidDrawIntoCanvas()) {
        continue;
      }

      auto surface =
          surface_producer_->ProduceSurface(layer.second.surface_size);
      if (!surface) {
        const std::string layer_id_str =
            layer.first.has_value() ? std::to_string(layer.first.value())
                                    : "Background";
        FML_LOG(ERROR) << "Failed to create surface for layer " << layer_id_str
                       << "; size (" << layer.second.surface_size.width()
                       << ", " << layer.second.surface_size.height() << ")";
        FML_DCHECK(false);
        continue;
      }

      // If we receive an unitialized surface, we need to first create flatland
      // resource.
      if (surface->GetImageId() == 0) {
        auto image_id = flatland_->NextContentId().value;
        const auto& size = surface->GetSize();
        fuchsia::ui::composition::ImageProperties image_properties;
        image_properties.set_size({static_cast<uint32_t>(size.width()),
                                   static_cast<uint32_t>(size.height())});
        flatland_->flatland()->CreateImage(
            {image_id}, surface->GetBufferCollectionImportToken(), 0,
            std::move(image_properties));

        surface->SetImageId(image_id);
        surface->SetReleaseImageCallback([flatland = flatland_, image_id]() {
          flatland->flatland()->ReleaseImage({image_id});
        });
      }

      // Enqueue fences for the next present.
      flatland_->EnqueueAcquireFence(surface->GetAcquireFence());
      flatland_->EnqueueReleaseFence(surface->GetReleaseFence());

      frame_surface_indices.emplace(
          std::make_pair(layer.first, frame_surfaces.size()));
      frame_surfaces.emplace_back(std::move(surface));
    }
  }

  // Finish recording SkPictures.
  {
    TRACE_EVENT0("flutter", "FinishRecordingPictures");

    for (const auto& surface_index : frame_surface_indices) {
      const auto& layer = frame_layers_.find(surface_index.first);
      FML_CHECK(layer != frame_layers_.end());
      layer->second.picture =
          layer->second.recorder->finishRecordingAsPicture();
      FML_CHECK(layer->second.picture != nullptr);
    }
  }

  // Submit layers and platform views to Scenic in composition order.
  {
    TRACE_EVENT0("flutter", "SubmitLayers");

    // First re-scale everything according to the DPR.
    const float inv_dpr = 1.0f / frame_dpr_;
    flatland_->flatland()->SetScale(root_transform_id_, {inv_dpr, inv_dpr});

    size_t flatland_layer_index = 0;
    for (const auto& layer_id : frame_composition_order_) {
      const auto& layer = frame_layers_.find(layer_id);
      FML_CHECK(layer != frame_layers_.end());

      // Draw the PlatformView associated with each layer first.
      if (layer_id.has_value()) {
        FML_CHECK(layer->second.embedded_view_params.has_value());
        auto& view_params = layer->second.embedded_view_params.value();

        // Get the FlatlandView structure corresponding to the platform view.
        auto found = flatland_views_.find(layer_id.value());
        FML_CHECK(found != flatland_views_.end())
            << "No FlatlandView for layer_id = " << layer_id.value()
            << ". This typically indicates that the Dart code in "
               "Fuchsia's fuchsia_scenic_flutter library failed to create "
               "the platform view, leading to a crash later down the road in "
               "the Flutter Engine code that tries to find that platform view. "
               "Check the Flutter Framework for changes to PlatformView that "
               "might have caused a regression.";
        auto& viewport = found->second;

        // Compute mutators, and size for the platform view.
        const ViewMutators view_mutators =
            ParseMutatorStack(view_params.mutatorsStack());
        const SkSize view_size = view_params.sizePoints();
        FML_CHECK(view_mutators.total_transform ==
                  view_params.transformMatrix());

        if (viewport.pending_create_viewport_callback) {
          if (view_size.fWidth && view_size.fHeight) {
            viewport.pending_create_viewport_callback(
                view_size, viewport.pending_occlusion_hint);
            viewport.size = view_size;
            viewport.occlusion_hint = viewport.pending_occlusion_hint;
          } else {
            FML_DLOG(WARNING)
                << "Failed to create viewport because width or height is zero.";
          }
        }

        // Set transform for the viewport.
        if (view_mutators.transform != viewport.mutators.transform) {
          flatland_->flatland()->SetTranslation(
              viewport.transform_id,
              {static_cast<int32_t>(view_mutators.transform.getTranslateX()),
               static_cast<int32_t>(view_mutators.transform.getTranslateY())});
          flatland_->flatland()->SetScale(
              viewport.transform_id, {view_mutators.transform.getScaleX(),
                                      view_mutators.transform.getScaleY()});
          viewport.mutators.transform = view_mutators.transform;
        }

        // TODO(fxbug.dev/94000): Set HitTestBehavior.

        // Set clip regions.
        if (view_mutators.clips != viewport.mutators.clips) {
          // Expand the clip_transforms array to fit any new transforms.
          while (viewport.clip_transforms.size() < view_mutators.clips.size()) {
            ClipTransform clip_transform;
            clip_transform.transform_id = flatland_->NextTransformId();
            flatland_->flatland()->CreateTransform(clip_transform.transform_id);
            viewport.clip_transforms.emplace_back(std::move(clip_transform));
          }
          FML_CHECK(viewport.clip_transforms.size() >=
                    view_mutators.clips.size());

          // Adjust and re-parent all clip transforms.
          for (auto& clip_transform : viewport.clip_transforms) {
            DetachClipTransformChildren(flatland_.get(), &clip_transform);
          }

          for (size_t c = 0; c < view_mutators.clips.size(); c++) {
            const SkMatrix& clip_matrix = view_mutators.clips[c].transform;
            const SkRect& clip_rect = view_mutators.clips[c].rect;

            flatland_->flatland()->SetTranslation(
                viewport.clip_transforms[c].transform_id,
                {static_cast<int32_t>(clip_matrix.getTranslateX()),
                 static_cast<int32_t>(clip_matrix.getTranslateY())});
            flatland_->flatland()->SetScale(
                viewport.clip_transforms[c].transform_id,
                {clip_matrix.getScaleX(), clip_matrix.getScaleY()});
            fuchsia::math::Rect rect = {
                static_cast<int32_t>(clip_rect.x()),
                static_cast<int32_t>(clip_rect.y()),
                static_cast<int32_t>(clip_rect.width()),
                static_cast<int32_t>(clip_rect.height())};
            flatland_->flatland()->SetClipBoundary(
                viewport.clip_transforms[c].transform_id,
                std::make_unique<fuchsia::math::Rect>(std::move(rect)));

            const auto child_transform_id =
                c != (view_mutators.clips.size() - 1)
                    ? viewport.clip_transforms[c + 1].transform_id
                    : viewport.transform_id;
            AttachClipTransformChild(flatland_.get(),
                                     &(viewport.clip_transforms[c]),
                                     child_transform_id);
          }
          viewport.mutators.clips = view_mutators.clips;
        }

        // Set opacity.
        if (view_mutators.opacity != viewport.mutators.opacity) {
          flatland_->flatland()->SetOpacity(viewport.transform_id,
                                            view_mutators.opacity);
          viewport.mutators.opacity = view_mutators.opacity;
        }

        // Set size and occlusion hint.
        if (view_size != viewport.size ||
            viewport.pending_occlusion_hint != viewport.occlusion_hint) {
          fuchsia::ui::composition::ViewportProperties properties;
          properties.set_logical_size(
              {static_cast<uint32_t>(view_size.fWidth),
               static_cast<uint32_t>(view_size.fHeight)});
          properties.set_inset(
              {static_cast<int32_t>(viewport.pending_occlusion_hint.fTop),
               static_cast<int32_t>(viewport.pending_occlusion_hint.fRight),
               static_cast<int32_t>(viewport.pending_occlusion_hint.fBottom),
               static_cast<int32_t>(viewport.pending_occlusion_hint.fLeft)});
          flatland_->flatland()->SetViewportProperties(viewport.viewport_id,
                                                       std::move(properties));
          viewport.size = view_size;
          viewport.occlusion_hint = viewport.pending_occlusion_hint;
        }

        // Attach the FlatlandView to the main scene graph.
        const auto main_child_transform =
            viewport.mutators.clips.empty()
                ? viewport.transform_id
                : viewport.clip_transforms[0].transform_id;
        flatland_->flatland()->AddChild(root_transform_id_,
                                        main_child_transform);
        child_transforms_.emplace_back(main_child_transform);
      }

      // Acquire the surface associated with the layer.
      SurfaceProducerSurface* surface_for_layer = nullptr;
      if (layer->second.canvas_spy->DidDrawIntoCanvas()) {
        const auto& surface_index = frame_surface_indices.find(layer_id);
        if (surface_index != frame_surface_indices.end()) {
          FML_CHECK(surface_index->second < frame_surfaces.size());
          surface_for_layer = frame_surfaces[surface_index->second].get();
          FML_CHECK(surface_for_layer != nullptr);
        } else {
          const std::string layer_id_str =
              layer_id.has_value() ? std::to_string(layer_id.value())
                                   : "Background";
          FML_LOG(ERROR) << "Missing surface for layer " << layer_id_str
                         << "; skipping scene graph add of layer.";
          FML_DCHECK(false);
        }
      }

      // Draw the layer if we acquired a surface for it successfully.
      if (surface_for_layer != nullptr) {
        // Create a new layer if needed for the surface.
        FML_CHECK(flatland_layer_index <= flatland_layers_.size());
        if (flatland_layer_index == flatland_layers_.size()) {
          FlatlandLayer new_layer{.transform_id = flatland_->NextTransformId()};
          flatland_->flatland()->CreateTransform(new_layer.transform_id);
          flatland_layers_.emplace_back(std::move(new_layer));
        }

        // Update the image content and set size.
        flatland_->flatland()->SetContent(
            flatland_layers_[flatland_layer_index].transform_id,
            {surface_for_layer->GetImageId()});
        flatland_->flatland()->SetImageDestinationSize(
            {surface_for_layer->GetImageId()},
            {static_cast<uint32_t>(surface_for_layer->GetSize().width()),
             static_cast<uint32_t>(surface_for_layer->GetSize().height())});

        // Flutter Embedder lacks an API to detect if a layer has alpha or not.
        // For now, we assume any layer beyond the first has alpha.
        flatland_->flatland()->SetImageBlendingFunction(
            {surface_for_layer->GetImageId()},
            flatland_layer_index == 0
                ? fuchsia::ui::composition::BlendMode::SRC
                : fuchsia::ui::composition::BlendMode::SRC_OVER);

        // Set hit regions for this layer; these hit regions correspond to the
        // portions of the layer on which skia drew content.
        {
          FML_CHECK(layer->second.rtree);
          std::list<SkRect> intersection_rects =
              layer->second.rtree->searchNonOverlappingDrawnRects(
                  SkRect::Make(layer->second.surface_size));

          std::vector<fuchsia::ui::composition::HitRegion> hit_regions;
          for (const SkRect& rect : intersection_rects) {
            hit_regions.emplace_back();
            auto& new_hit_region = hit_regions.back();
            new_hit_region.region.x = rect.x();
            new_hit_region.region.y = rect.y();
            new_hit_region.region.width = rect.width();
            new_hit_region.region.height = rect.height();
            new_hit_region.hit_test =
                fuchsia::ui::composition::HitTestInteraction::DEFAULT;
          }

          flatland_->flatland()->SetHitRegions(
              flatland_layers_[flatland_layer_index].transform_id,
              std::move(hit_regions));
        }

        // Attach the FlatlandLayer to the main scene graph.
        flatland_->flatland()->AddChild(
            root_transform_id_,
            flatland_layers_[flatland_layer_index].transform_id);
        child_transforms_.emplace_back(
            flatland_layers_[flatland_layer_index].transform_id);
      }

      // Reset for the next pass:
      flatland_layer_index++;
    }

    // Set up the input interceptor at the top of the
    // scene, if applicable.  It will capture all input, and any unwanted input
    // will be reinjected into embedded views.
    if (input_interceptor_transform_.has_value()) {
      flatland_->flatland()->AddChild(root_transform_id_,
                                      *input_interceptor_transform_);
      child_transforms_.emplace_back(*input_interceptor_transform_);
    }
  }

  // Present the session to Scenic, along with surface acquire/release fences.
  {
    TRACE_EVENT0("flutter", "SessionPresent");

    flatland_->Present();
  }

  // Render the recorded SkPictures into the surfaces.
  {
    TRACE_EVENT0("flutter", "RasterizeSurfaces");

    for (const auto& surface_index : frame_surface_indices) {
      TRACE_EVENT0("flutter", "RasterizeSurface");

      FML_CHECK(surface_index.second < frame_surfaces.size());
      SurfaceProducerSurface* surface =
          frame_surfaces[surface_index.second].get();
      FML_CHECK(surface != nullptr);

      sk_sp<SkSurface> sk_surface = surface->GetSkiaSurface();
      FML_CHECK(sk_surface != nullptr);
      FML_CHECK(SkISize::Make(sk_surface->width(), sk_surface->height()) ==
                frame_size_);
      SkCanvas* canvas = sk_surface->getCanvas();
      FML_CHECK(canvas != nullptr);

      const auto& layer = frame_layers_.find(surface_index.first);
      FML_CHECK(layer != frame_layers_.end());

      canvas->setMatrix(SkMatrix::I());
      canvas->clear(SK_ColorTRANSPARENT);
      canvas->drawPicture(layer->second.picture);
      canvas->flush();
    }
  }

  // Flush deferred Skia work and inform Scenic that render targets are ready.
  {
    TRACE_EVENT0("flutter", "PresentSurfaces");

    surface_producer_->SubmitSurfaces(std::move(frame_surfaces));
  }

  // Submit the underlying render-backend-specific frame for processing.
  frame->Submit();
}

void FlatlandExternalViewEmbedder::CreateView(
    int64_t view_id,
    ViewCallback on_view_created,
    FlatlandViewCreatedCallback on_view_bound) {
  FML_CHECK(flatland_views_.find(view_id) == flatland_views_.end());

  const auto transform_id = flatland_->NextTransformId();
  const auto viewport_id = flatland_->NextContentId();
  FlatlandView new_view = {.transform_id = transform_id,
                           .viewport_id = viewport_id};
  flatland_->flatland()->CreateTransform(new_view.transform_id);
  fuchsia::ui::composition::ChildViewWatcherHandle child_view_watcher;
  new_view.pending_create_viewport_callback =
      [this, transform_id, viewport_id, view_id,
       child_view_watcher_request = child_view_watcher.NewRequest()](
          const SkSize& size, const SkRect& inset) mutable {
        fuchsia::ui::composition::ViewportProperties properties;
        properties.set_logical_size({static_cast<uint32_t>(size.fWidth),
                                     static_cast<uint32_t>(size.fHeight)});
        properties.set_inset({static_cast<int32_t>(inset.fTop),
                              static_cast<int32_t>(inset.fRight),
                              static_cast<int32_t>(inset.fBottom),
                              static_cast<int32_t>(inset.fLeft)});
        flatland_->flatland()->CreateViewport(
            viewport_id, {zx::channel((zx_handle_t)view_id)},
            std::move(properties), std::move(child_view_watcher_request));
        flatland_->flatland()->SetContent(transform_id, viewport_id);
      };

  on_view_created();
  on_view_bound(new_view.viewport_id, std::move(child_view_watcher));
  flatland_views_.emplace(std::make_pair(view_id, std::move(new_view)));
}

void FlatlandExternalViewEmbedder::DestroyView(
    int64_t view_id,
    FlatlandViewIdCallback on_view_unbound) {
  auto flatland_view = flatland_views_.find(view_id);
  FML_CHECK(flatland_view != flatland_views_.end());

  auto viewport_id = flatland_view->second.viewport_id;
  auto transform_id = flatland_view->second.transform_id;
  auto& clip_transforms = flatland_view->second.clip_transforms;
  if (!flatland_view->second.pending_create_viewport_callback) {
    flatland_->flatland()->ReleaseViewport(viewport_id, [](auto) {});
  }
  auto itr = std::find_if(
      child_transforms_.begin(), child_transforms_.end(),
      [transform_id,
       &clip_transforms](fuchsia::ui::composition::TransformId id) {
        return id.value == transform_id.value ||
               (!clip_transforms.empty() &&
                (id.value == clip_transforms[0].transform_id.value));
      });
  if (itr != child_transforms_.end()) {
    flatland_->flatland()->RemoveChild(root_transform_id_, *itr);
    child_transforms_.erase(itr);
  }
  for (auto& clip_transform : clip_transforms) {
    DetachClipTransformChildren(flatland_.get(), &clip_transform);
  }
  flatland_->flatland()->ReleaseTransform(transform_id);
  for (auto& clip_transform : clip_transforms) {
    flatland_->flatland()->ReleaseTransform(clip_transform.transform_id);
  }

  flatland_views_.erase(flatland_view);
  on_view_unbound(viewport_id);
}

void FlatlandExternalViewEmbedder::SetViewProperties(
    int64_t view_id,
    const SkRect& occlusion_hint,
    bool hit_testable,
    bool focusable) {
  auto found = flatland_views_.find(view_id);
  FML_CHECK(found != flatland_views_.end());

  // Note that pending_create_viewport_callback might not have run at this
  // point.
  auto& viewport = found->second;
  viewport.pending_occlusion_hint = occlusion_hint;
}

void FlatlandExternalViewEmbedder::Reset() {
  frame_layers_.clear();
  frame_composition_order_.clear();
  frame_size_ = SkISize::Make(0, 0);
  frame_dpr_ = 1.f;

  // Clear all children from root.
  for (const auto& transform : child_transforms_) {
    flatland_->flatland()->RemoveChild(root_transform_id_, transform);
  }
  child_transforms_.clear();

  // Clear images on all layers so they aren't cached unnecessarily.
  for (const auto& layer : flatland_layers_) {
    flatland_->flatland()->SetContent(layer.transform_id, {0});
  }
}

FlatlandExternalViewEmbedder::ViewMutators
FlatlandExternalViewEmbedder::ParseMutatorStack(
    const flutter::MutatorsStack& mutators_stack) {
  ViewMutators mutators;
  SkMatrix total_transform = SkMatrix::I();
  SkMatrix transform_accumulator = SkMatrix::I();

  for (auto i = mutators_stack.Begin(); i != mutators_stack.End(); ++i) {
    const auto& mutator = *i;
    switch (mutator->GetType()) {
      case flutter::MutatorType::kOpacity: {
        mutators.opacity *= std::clamp(mutator->GetAlphaFloat(), 0.f, 1.f);
      } break;
      case flutter::MutatorType::kTransform: {
        total_transform.preConcat(mutator->GetMatrix());
        transform_accumulator.preConcat(mutator->GetMatrix());
      } break;
      case flutter::MutatorType::kClipRect: {
        mutators.clips.emplace_back(TransformedClip{
            .transform = transform_accumulator,
            .rect = mutator->GetRect(),
        });
        transform_accumulator = SkMatrix::I();
      } break;
      case flutter::MutatorType::kClipRRect: {
        mutators.clips.emplace_back(TransformedClip{
            .transform = transform_accumulator,
            .rect = mutator->GetRRect().getBounds(),
        });
        transform_accumulator = SkMatrix::I();
      } break;
      case flutter::MutatorType::kClipPath: {
        mutators.clips.emplace_back(TransformedClip{
            .transform = transform_accumulator,
            .rect = mutator->GetPath().getBounds(),
        });
        transform_accumulator = SkMatrix::I();
      } break;
      default: {
        break;
      }
    }
  }
  mutators.total_transform = total_transform;
  mutators.transform = transform_accumulator;
  mutators.opacity = std::clamp(mutators.opacity, 0.f, 1.f);

  return mutators;
}

}  // namespace flutter_runner
