// 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/view_holder.h"

#include "flutter/fml/thread_local.h"

namespace {

using ViewHolderBindings =
    std::unordered_map<zx_koid_t, std::unique_ptr<flutter::ViewHolder>>;

FML_THREAD_LOCAL fml::ThreadLocalUniquePtr<ViewHolderBindings>
    tls_view_holder_bindings;

fuchsia::ui::gfx::ViewProperties ToViewProperties(float width,
                                                  float height,
                                                  float insetTop,
                                                  float insetRight,
                                                  float insetBottom,
                                                  float insetLeft,
                                                  bool focusable) {
  return fuchsia::ui::gfx::ViewProperties({
      .bounding_box = fuchsia::ui::gfx::BoundingBox({
          .min = fuchsia::ui::gfx::vec3({
              .x = 0.f,
              .y = 0.f,
              .z = -1000.f,
          }),
          .max = fuchsia::ui::gfx::vec3({.x = width, .y = height, .z = 0.f}),
      }),
      .inset_from_min = fuchsia::ui::gfx::vec3({
          .x = insetLeft,
          .y = insetTop,
          .z = 0.f,
      }),
      .inset_from_max = fuchsia::ui::gfx::vec3({
          .x = insetRight,
          .y = insetBottom,
          .z = 0.f,
      }),
      .focus_change = focusable,
  });
}

}  // namespace

namespace flutter {

void ViewHolder::Create(zx_koid_t id,
                        fml::RefPtr<fml::TaskRunner> ui_task_runner,
                        fuchsia::ui::views::ViewHolderToken view_holder_token,
                        BindCallback on_bind_callback) {
  // This GPU thread contains at least 1 ViewHolder.  Initialize the per-thread
  // bindings.
  if (tls_view_holder_bindings.get() == nullptr) {
    tls_view_holder_bindings.reset(new ViewHolderBindings());
  }

  auto* bindings = tls_view_holder_bindings.get();
  FML_DCHECK(bindings);
  FML_DCHECK(bindings->find(id) == bindings->end());

  auto view_holder = std::make_unique<ViewHolder>(std::move(ui_task_runner),
                                                  std::move(view_holder_token),
                                                  std::move(on_bind_callback));
  bindings->emplace(id, std::move(view_holder));
}

void ViewHolder::Destroy(zx_koid_t id) {
  auto* bindings = tls_view_holder_bindings.get();
  FML_DCHECK(bindings);

  bindings->erase(id);
}

ViewHolder* ViewHolder::FromId(zx_koid_t id) {
  auto* bindings = tls_view_holder_bindings.get();
  if (!bindings) {
    return nullptr;
  }

  auto binding = bindings->find(id);
  if (binding == bindings->end()) {
    return nullptr;
  }

  return binding->second.get();
}

ViewHolder::ViewHolder(fml::RefPtr<fml::TaskRunner> ui_task_runner,
                       fuchsia::ui::views::ViewHolderToken view_holder_token,
                       BindCallback on_bind_callback)
    : ui_task_runner_(std::move(ui_task_runner)),
      pending_view_holder_token_(std::move(view_holder_token)),
      pending_bind_callback_(std::move(on_bind_callback)) {
  FML_DCHECK(ui_task_runner_);
  FML_DCHECK(pending_view_holder_token_.value);
}

void ViewHolder::UpdateScene(SceneUpdateContext& context,
                             const SkPoint& offset,
                             const SkSize& size,
                             bool hit_testable) {
  if (pending_view_holder_token_.value) {
    opacity_node_ =
        std::make_unique<scenic::OpacityNodeHACK>(context.session());
    entity_node_ = std::make_unique<scenic::EntityNode>(context.session());
    view_holder_ = std::make_unique<scenic::ViewHolder>(
        context.session(), std::move(pending_view_holder_token_),
        "Flutter SceneHost");

    opacity_node_->AddChild(*entity_node_);
    entity_node_->Attach(*view_holder_);
    ui_task_runner_->PostTask(
        [bind_callback = std::move(pending_bind_callback_),
         view_holder_id = view_holder_->id()]() {
          bind_callback(view_holder_id);
        });
  }
  FML_DCHECK(opacity_node_);
  FML_DCHECK(view_holder_);

  context.top_entity()->entity_node().AddChild(*opacity_node_);
  entity_node_->SetTranslation(offset.x(), offset.y(), -0.1f);
  entity_node_->SetHitTestBehavior(
      hit_testable ? fuchsia::ui::gfx::HitTestBehavior::kDefault
                   : fuchsia::ui::gfx::HitTestBehavior::kSuppress);
  if (has_pending_opacity_) {
    opacity_node_->SetOpacity(pending_opacity_);

    has_pending_opacity_ = false;
  }
  if (has_pending_properties_) {
    view_holder_->SetViewProperties(std::move(pending_properties_));

    has_pending_properties_ = false;
  }
}

void ViewHolder::SetProperties(double width,
                               double height,
                               double insetTop,
                               double insetRight,
                               double insetBottom,
                               double insetLeft,
                               bool focusable) {
  pending_properties_ = ToViewProperties(width, height, insetTop, insetRight,
                                         insetBottom, insetLeft, focusable);
  has_pending_properties_ = true;
}

void ViewHolder::SetOpacity(double opacity) {
  pending_opacity_ = std::clamp(opacity, 0.0, 1.0);
  has_pending_opacity_ = true;
}

}  // namespace flutter
