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

constexpr uint32_t kFlatlandDefaultViewportSize = 32;

FlatlandExternalViewEmbedder::FlatlandExternalViewEmbedder(
    std::string debug_label,
    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,
    FlatlandConnection& flatland,
    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_);
}

FlatlandExternalViewEmbedder::~FlatlandExternalViewEmbedder() = default;

SkCanvas* FlatlandExternalViewEmbedder::GetRootCanvas() {
  auto found = frame_layers_.find(kRootLayerId);
  if (found == frame_layers_.end()) {
    FML_DLOG(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;
}

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)));
  frame_composition_order_.push_back(handle);
}

SkCanvas* 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();
}

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;

  // TODO(fxbug.dev/64201): Handle device pixel ratio.

  // Create the root layer.
  frame_layers_.emplace(
      std::make_pair(kRootLayerId, EmbedderLayer(frame_size, std::nullopt)));
  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));
    }
  }

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

    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());
        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());

        // TODO(fxbug.dev/64201): Handle clips.

        // Set transform for the viewport.
        // TODO(fxbug.dev/64201): Handle scaling.
        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())});
          viewport.mutators.transform = view_mutators.transform;
        }

        // TODO(fxbug.dev/64201): Set HitTestBehavior.
        // TODO(fxbug.dev/64201): Set opacity.

        // Set size
        // TODO(): Set occlusion hint, and focusable.
        if (view_size != viewport.size) {
          fuchsia::ui::composition::ViewportProperties properties;
          properties.set_logical_size(
              {static_cast<uint32_t>(view_size.fWidth),
               static_cast<uint32_t>(view_size.fHeight)});
          flatland_.flatland()->SetViewportProperties(viewport.viewport_id,
                                                      std::move(properties));
          viewport.size = view_size;
        }

        // Attach the FlatlandView to the main scene graph.
        flatland_.flatland()->AddChild(root_transform_id_,
                                       viewport.transform_id);
        child_transforms_.emplace_back(viewport.transform_id);
      }

      // 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())});

        // 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:
      //  +The next layer will not be the first layer.
      flatland_layer_index++;
    }
  }

  // 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());
      sk_sp<SkPicture> picture =
          layer->second.recorder->finishRecordingAsPicture();
      FML_CHECK(picture != nullptr);

      canvas->setMatrix(SkMatrix::I());
      canvas->clear(SK_ColorTRANSPARENT);
      canvas->drawPicture(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());

  FlatlandView new_view = {.transform_id = flatland_.NextTransformId(),
                           .viewport_id = flatland_.NextContentId()};
  flatland_.flatland()->CreateTransform(new_view.transform_id);
  fuchsia::ui::composition::ViewportProperties properties;
  // TODO(fxbug.dev/64201): Investigate if it is possible to avoid using a
  // default size by finding the size before creation.
  properties.set_logical_size(
      {kFlatlandDefaultViewportSize, kFlatlandDefaultViewportSize});
  fuchsia::ui::composition::ChildViewWatcherPtr child_view_watcher;
  flatland_.flatland()->CreateViewport(
      new_view.viewport_id, {zx::channel((zx_handle_t)view_id)},
      std::move(properties), child_view_watcher.NewRequest());
  flatland_.flatland()->SetContent(new_view.transform_id, new_view.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;
  flatland_.flatland()->ReleaseViewport(viewport_id, [](auto) {});
  auto itr =
      std::find_if(child_transforms_.begin(), child_transforms_.end(),
                   [transform_id](fuchsia::ui::composition::TransformId id) {
                     return id.value == transform_id.value;
                   });
  if (itr != child_transforms_.end()) {
    flatland_.flatland()->RemoveChild(root_transform_id_, transform_id);
    child_transforms_.erase(itr);
  }
  flatland_.flatland()->ReleaseTransform(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());

  // TODO(fxbug.dev/64201): Set occlusion_hint, hit_testable and focusable.
}

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

  // 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::opacity: {
        mutators.opacity *= std::clamp(mutator->GetAlphaFloat(), 0.f, 1.f);
      } break;
      case flutter::MutatorType::transform: {
        total_transform.preConcat(mutator->GetMatrix());
        transform_accumulator.preConcat(mutator->GetMatrix());
      } break;
      case flutter::MutatorType::clip_rect: {
        mutators.clips.emplace_back(TransformedClip{
            .transform = transform_accumulator,
            .rect = mutator->GetRect(),
        });
        transform_accumulator = SkMatrix::I();
      } break;
      case flutter::MutatorType::clip_rrect: {
        mutators.clips.emplace_back(TransformedClip{
            .transform = transform_accumulator,
            .rect = mutator->GetRRect().getBounds(),
        });
        transform_accumulator = SkMatrix::I();
      } break;
      case flutter::MutatorType::clip_path: {
        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
