// 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,
                        const BindCallback& on_bind_callback) {
  // This raster 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),
                                                  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,
                       const BindCallback& on_bind_callback)
    : ui_task_runner_(std::move(ui_task_runner)),
      pending_view_holder_token_(std::move(view_holder_token)),
      pending_bind_callback_(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,
                             SkAlpha opacity,
                             bool hit_testable) {
  if (pending_view_holder_token_.value) {
    entity_node_ = std::make_unique<scenic::EntityNode>(context.session());
    opacity_node_ =
        std::make_unique<scenic::OpacityNodeHACK>(context.session());
    view_holder_ = std::make_unique<scenic::ViewHolder>(
        context.session(), std::move(pending_view_holder_token_),
        "Flutter SceneHost");
    opacity_node_->AddChild(*entity_node_);
    opacity_node_->SetLabel("flutter::ViewHolder");
    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(entity_node_);
  FML_DCHECK(opacity_node_);
  FML_DCHECK(view_holder_);

  context.top_entity()->embedder_node().AddChild(*opacity_node_);
  opacity_node_->SetOpacity(opacity / 255.0f);
  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_properties_) {
    // TODO(dworsham): This should be derived from size and elevation.  We
    // should be able to Z-limit the view's box but otherwise it uses all of the
    // available airspace.
    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;
}

}  // namespace flutter
