// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/flow/scene_update_context.h"

#include <lib/ui/scenic/cpp/commands.h>
#include <lib/ui/scenic/cpp/view_token_pair.h>

#include "flutter/flow/layers/layer.h"
#include "flutter/flow/matrix_decomposition.h"
#include "flutter/flow/view_holder.h"
#include "flutter/fml/trace_event.h"
#include "include/core/SkColor.h"

namespace flutter {
namespace {

void SetEntityNodeClipPlanes(scenic::EntityNode& entity_node,
                             const SkRect& bounds) {
  const float top = bounds.top();
  const float bottom = bounds.bottom();
  const float left = bounds.left();
  const float right = bounds.right();

  // We will generate 4 oriented planes, one for each edge of the bounding rect.
  std::vector<fuchsia::ui::gfx::Plane3> clip_planes;
  clip_planes.resize(4);

  // Top plane.
  clip_planes[0].dist = top;
  clip_planes[0].dir.x = 0.f;
  clip_planes[0].dir.y = 1.f;
  clip_planes[0].dir.z = 0.f;

  // Bottom plane.
  clip_planes[1].dist = -bottom;
  clip_planes[1].dir.x = 0.f;
  clip_planes[1].dir.y = -1.f;
  clip_planes[1].dir.z = 0.f;

  // Left plane.
  clip_planes[2].dist = left;
  clip_planes[2].dir.x = 1.f;
  clip_planes[2].dir.y = 0.f;
  clip_planes[2].dir.z = 0.f;

  // Right plane.
  clip_planes[3].dist = -right;
  clip_planes[3].dir.x = -1.f;
  clip_planes[3].dir.y = 0.f;
  clip_planes[3].dir.z = 0.f;

  entity_node.SetClipPlanes(std::move(clip_planes));
}

void SetMaterialColor(scenic::Material& material,
                      SkColor color,
                      SkAlpha opacity) {
  const SkAlpha color_alpha = static_cast<SkAlpha>(
      ((float)SkColorGetA(color) * (float)opacity) / 255.0f);
  material.SetColor(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color),
                    color_alpha);
}

}  // namespace

SceneUpdateContext::SceneUpdateContext(std::string debug_label,
                                       fuchsia::ui::views::ViewToken view_token,
                                       scenic::ViewRefPair view_ref_pair,
                                       SessionWrapper& session,
                                       bool intercept_all_input)
    : session_(session),
      root_view_(session_.get(),
                 std::move(view_token),
                 std::move(view_ref_pair.control_ref),
                 std::move(view_ref_pair.view_ref),
                 debug_label),
      metrics_node_(session.get()),
      layer_tree_node_(session_.get()) {
  layer_tree_node_.SetLabel("Flutter::LayerTree");
  metrics_node_.SetLabel("Flutter::MetricsWatcher");
  metrics_node_.SetEventMask(fuchsia::ui::gfx::kMetricsEventMask);
  metrics_node_.AddChild(layer_tree_node_);
  root_view_.AddChild(metrics_node_);

  // 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 (intercept_all_input) {
    input_interceptor_node_.emplace(session_.get());
    input_interceptor_node_->SetLabel("Flutter::InputInterceptor");
    input_interceptor_node_->SetHitTestBehavior(
        fuchsia::ui::gfx::HitTestBehavior::kDefault);
    input_interceptor_node_->SetSemanticVisibility(false);

    metrics_node_.AddChild(input_interceptor_node_.value());
  }

  session_.Present();
}

std::vector<SceneUpdateContext::PaintTask> SceneUpdateContext::GetPaintTasks() {
  std::vector<PaintTask> frame_paint_tasks = std::move(paint_tasks_);

  paint_tasks_.clear();

  return frame_paint_tasks;
}

void SceneUpdateContext::EnableWireframe(bool enable) {
  session_.get()->Enqueue(
      scenic::NewSetEnableDebugViewBoundsCmd(root_view_.id(), enable));
}

void SceneUpdateContext::Reset(const SkISize& frame_size,
                               float device_pixel_ratio) {
  paint_tasks_.clear();
  top_entity_ = nullptr;
  top_scale_x_ = 1.f;
  top_scale_y_ = 1.f;
  top_elevation_ = 0.f;
  next_elevation_ = 0.f;
  alpha_ = 1.f;

  // Adjust scene scaling to match the device pixel ratio.
  const float inv_dpr = 1.0f / device_pixel_ratio;
  layer_tree_node_.SetScale(inv_dpr, inv_dpr, 1.0f);

  // Set up the input interceptor at the top of the scene, if applicable.
  if (input_interceptor_node_.has_value()) {
    // TODO(fxb/): Don't hardcode elevation.
    input_interceptor_node_->SetTranslation(frame_size.width() * 0.5f,
                                            frame_size.height() * 0.5f, -100.f);
    input_interceptor_node_->SetShape(scenic::Rectangle(
        session_.get(), frame_size.width(), frame_size.height()));
  }

  // We are going to be sending down a fresh node hierarchy every frame. So just
  // enqueue a detach op on the layer tree node.
  layer_tree_node_.DetachChildren();
}

void SceneUpdateContext::CreateFrame(scenic::EntityNode& entity_node,
                                     const SkRRect& rrect,
                                     SkColor color,
                                     SkAlpha opacity,
                                     const SkRect& paint_bounds,
                                     std::vector<Layer*> paint_layers) {
  // We don't need a shape if the frame is zero size.
  if (rrect.isEmpty())
    return;

  // Frames always clip their children.
  SkRect shape_bounds = rrect.getBounds();
  SetEntityNodeClipPlanes(entity_node, shape_bounds);

  // TODO(SCN-137): Need to be able to express the radii as vectors.
  scenic::ShapeNode shape_node(session_.get());
  scenic::Rectangle shape(session_.get(), rrect.width(), rrect.height());
  shape_node.SetShape(shape);
  shape_node.SetTranslation(shape_bounds.width() * 0.5f + shape_bounds.left(),
                            shape_bounds.height() * 0.5f + shape_bounds.top(),
                            0.f);

  // Check whether the painted layers will be visible.
  if (paint_bounds.isEmpty() || !paint_bounds.intersects(shape_bounds))
    paint_layers.clear();

  scenic::Material material(session_.get());
  shape_node.SetMaterial(material);
  entity_node.AddChild(shape_node);

  // Check whether a solid color will suffice.
  if (paint_layers.empty()) {
    SetMaterialColor(material, color, opacity);
  } else {
    // The final shape's color is material_color * texture_color.  The passed in
    // material color was already used as a background when generating the
    // texture, so set the model color to |SK_ColorWHITE| in order to allow
    // using the texture's color unmodified.
    SetMaterialColor(material, SK_ColorWHITE, opacity);

    // Enqueue a paint task for these layers, to apply a texture to the whole
    // shape.
    //
    // The task uses the |shape_bounds| as its rendering bounds instead of the
    // |paint_bounds|.  If the paint_bounds is large than the shape_bounds it
    // will be clipped.
    paint_tasks_.emplace_back(PaintTask{.paint_bounds = shape_bounds,
                                        .scale_x = top_scale_x_,
                                        .scale_y = top_scale_y_,
                                        .background_color = color,
                                        .material = std::move(material),
                                        .layers = std::move(paint_layers)});
  }
}

void SceneUpdateContext::UpdateView(int64_t view_id,
                                    const SkPoint& offset,
                                    const SkSize& size,
                                    std::optional<bool> override_hit_testable) {
  auto* view_holder = ViewHolder::FromId(view_id);
  if (view_holder == nullptr) {
    FML_LOG(ERROR) << "UpdateView did not find view holder for: " << view_id;
    return;
  }

  if (override_hit_testable.has_value()) {
    view_holder->set_hit_testable(*override_hit_testable);
  }
  view_holder->set_size(size);
  view_holder->UpdateScene(session_.get(), top_entity_->embedder_node(), offset,
                           SkScalarRoundToInt(alphaf() * 255));

  // Assume embedded views are 10 "layers" wide.
  next_elevation_ += 10 * kScenicZElevationBetweenLayers;
}

void SceneUpdateContext::CreateView(int64_t view_id,
                                    ViewCallback on_view_created,
                                    ViewHolder::ViewIdCallback on_view_bound,
                                    bool hit_testable,
                                    bool focusable) {
  FML_LOG(INFO) << "CreateView for view holder: " << view_id;
  zx_handle_t handle = (zx_handle_t)view_id;
  flutter::ViewHolder::Create(handle, std::move(on_view_bound),
                              scenic::ToViewHolderToken(zx::eventpair(handle)));
  on_view_created();

  auto* view_holder = ViewHolder::FromId(view_id);
  FML_DCHECK(view_holder);
  view_holder->set_hit_testable(hit_testable);
  view_holder->set_focusable(focusable);
}

void SceneUpdateContext::UpdateView(int64_t view_id,
                                    const SkRect& view_occlusion_hint,
                                    bool hit_testable,
                                    bool focusable) {
  auto* view_holder = ViewHolder::FromId(view_id);
  if (view_holder == nullptr) {
    FML_LOG(ERROR) << "UpdateView did not find view holder for: " << view_id;
    return;
  }

  view_holder->set_hit_testable(hit_testable);
  view_holder->set_focusable(focusable);
  view_holder->set_occlusion_hint(view_occlusion_hint);
}

void SceneUpdateContext::DestroyView(
    int64_t view_id,
    ViewHolder::ViewIdCallback on_view_destroyed) {
  ViewHolder::Destroy(view_id, std::move(on_view_destroyed));
}

SceneUpdateContext::Entity::Entity(std::shared_ptr<SceneUpdateContext> context)
    : context_(context),
      previous_entity_(context->top_entity_),
      entity_node_(context->session_.get()) {
  context->top_entity_ = this;
}

SceneUpdateContext::Entity::~Entity() {
  if (previous_entity_) {
    previous_entity_->embedder_node().AddChild(entity_node_);
  } else {
    context_->layer_tree_node_.AddChild(entity_node_);
  }

  FML_DCHECK(context_->top_entity_ == this);
  context_->top_entity_ = previous_entity_;
}

SceneUpdateContext::Transform::Transform(
    std::shared_ptr<SceneUpdateContext> context,
    const SkMatrix& transform)
    : Entity(context),
      previous_scale_x_(context->top_scale_x_),
      previous_scale_y_(context->top_scale_y_) {
  entity_node().SetLabel("flutter::Transform");
  if (!transform.isIdentity()) {
    // TODO(SCN-192): The perspective and shear components in the matrix
    // are not handled correctly.
    MatrixDecomposition decomposition(transform);
    if (decomposition.IsValid()) {
      // Don't allow clients to control the z dimension; we control that
      // instead to make sure layers appear in proper order.
      entity_node().SetTranslation(decomposition.translation().x,  //
                                   decomposition.translation().y,  //
                                   0.f                             //
      );

      entity_node().SetScale(decomposition.scale().x,  //
                             decomposition.scale().y,  //
                             1.f                       //
      );
      context->top_scale_x_ *= decomposition.scale().x;
      context->top_scale_y_ *= decomposition.scale().y;

      entity_node().SetRotation(decomposition.rotation().x,  //
                                decomposition.rotation().y,  //
                                decomposition.rotation().z,  //
                                decomposition.rotation().w   //
      );
    }
  }
}

SceneUpdateContext::Transform::Transform(
    std::shared_ptr<SceneUpdateContext> context,
    float scale_x,
    float scale_y,
    float scale_z)
    : Entity(context),
      previous_scale_x_(context->top_scale_x_),
      previous_scale_y_(context->top_scale_y_) {
  entity_node().SetLabel("flutter::Transform");
  if (scale_x != 1.f || scale_y != 1.f || scale_z != 1.f) {
    entity_node().SetScale(scale_x, scale_y, scale_z);
    context->top_scale_x_ *= scale_x;
    context->top_scale_y_ *= scale_y;
  }
}

SceneUpdateContext::Transform::~Transform() {
  context()->top_scale_x_ = previous_scale_x_;
  context()->top_scale_y_ = previous_scale_y_;
}

SceneUpdateContext::Frame::Frame(std::shared_ptr<SceneUpdateContext> context,
                                 const SkRRect& rrect,
                                 SkColor color,
                                 SkAlpha opacity,
                                 std::string label)
    : Entity(context),
      previous_elevation_(context->top_elevation_),
      rrect_(rrect),
      color_(color),
      opacity_(opacity),
      opacity_node_(context->session_.get()),
      paint_bounds_(SkRect::MakeEmpty()) {
  // Increment elevation trackers before calculating any local elevation.
  // |UpdateView| can modify context->next_elevation_, which is why it is
  // necessary to track this additional state.
  context->top_elevation_ += kScenicZElevationBetweenLayers;
  context->next_elevation_ += kScenicZElevationBetweenLayers;

  float local_elevation = context->next_elevation_ - previous_elevation_;
  entity_node().SetTranslation(0.f, 0.f, -local_elevation);
  entity_node().SetLabel(label);
  entity_node().AddChild(opacity_node_);

  // Scenic currently lacks an API to enable rendering of alpha channel; alpha
  // channels are only rendered if there is a OpacityNode higher in the tree
  // with opacity != 1. For now, clamp to a infinitesimally smaller value than
  // 1, which does not cause visual problems in practice.
  opacity_node_.SetOpacity(std::min(kOneMinusEpsilon, opacity_ / 255.0f));
}

SceneUpdateContext::Frame::~Frame() {
  context()->top_elevation_ = previous_elevation_;

  // Add a part which represents the frame's geometry for clipping purposes
  context()->CreateFrame(entity_node(), rrect_, color_, opacity_, paint_bounds_,
                         std::move(paint_layers_));
}

void SceneUpdateContext::Frame::AddPaintLayer(Layer* layer) {
  FML_DCHECK(!layer->is_empty());
  paint_layers_.push_back(layer);
  paint_bounds_.join(layer->paint_bounds());
}

SceneUpdateContext::Clip::Clip(std::shared_ptr<SceneUpdateContext> context,
                               const SkRect& shape_bounds)
    : Entity(context) {
  entity_node().SetLabel("flutter::Clip");
  SetEntityNodeClipPlanes(entity_node(), shape_bounds);
}

}  // namespace flutter
