// Copyright 2019 The Fuchsia 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 "src/ui/scenic/lib/flatland/link_system.h"

#include <lib/syslog/cpp/macros.h>

#include <glm/gtc/matrix_access.hpp>

using fuchsia::ui::composition::ChildViewStatus;
using fuchsia::ui::composition::ChildViewWatcher;
using fuchsia::ui::composition::LayoutInfo;
using fuchsia::ui::composition::ParentViewportStatus;
using fuchsia::ui::composition::ParentViewportWatcher;
using fuchsia::ui::views::ViewCreationToken;
using fuchsia::ui::views::ViewportCreationToken;

namespace flatland {

namespace {

// Scale can be extracted from a matrix by finding the length of the
// column the scale is located in:
//
//   a b c
//   e f g
//   i j k
//
// If |a| is the x scale and rotation, and |f| is the y scale and rotation, then
// we can calculate the x scale with length(vector(a,e,i)) and y scale with
// length(vector(b,f,j)).
glm::vec2 ComputeScale(const glm::mat3& matrix) {
  const glm::vec3 x_column = glm::column(matrix, 0);
  const glm::vec3 y_column = glm::column(matrix, 1);
  return {glm::length(x_column), glm::length(y_column)};
}

}  // namespace

LinkSystem::LinkSystem(TransformHandle::InstanceId instance_id)
    : instance_id_(instance_id), link_graph_(instance_id_), linker_(ObjectLinker::New()) {}

LinkSystem::ChildLink LinkSystem::CreateChildLink(
    std::shared_ptr<utils::DispatcherHolder> dispatcher_holder, ViewportCreationToken token,
    fuchsia::ui::composition::ViewportProperties initial_properties,
    fidl::InterfaceRequest<ChildViewWatcher> child_view_watcher,
    TransformHandle parent_viewport_watcher_handle, LinkProtocolErrorCallback error_callback) {
  FX_DCHECK(token.value.is_valid());
  FX_DCHECK(initial_properties.has_logical_size());

  auto impl = std::make_shared<ChildViewWatcherImpl>(dispatcher_holder,
                                                     std::move(child_view_watcher), error_callback);
  const TransformHandle link_handle = CreateTransformLocked();

  ObjectLinker::ImportLink importer = linker_->CreateImport(
      ChildLinkInfo{.parent_viewport_watcher_handle = parent_viewport_watcher_handle,
                    .link_handle = link_handle,
                    .initial_logical_size = initial_properties.logical_size()},
      std::move(token.value),
      /* error_reporter */ nullptr);

  auto child_view_watcher_map_key = std::make_shared<TransformHandle>();
  importer.Initialize(
      /* link_resolved = */
      [ref = shared_from_this(), impl, child_view_watcher_map_key](ParentLinkInfo info) mutable {
        *child_view_watcher_map_key = info.child_view_watcher_handle;
        if (info.view_ref != nullptr) {
          impl->SetViewRef({.reference = utils::CopyEventpair(info.view_ref->reference)});
        }
        std::scoped_lock lock(ref->mutex_);
        ref->child_view_watcher_map_[*child_view_watcher_map_key] = impl;
      },
      /* link_invalidated = */
      [ref = shared_from_this(), impl, child_view_watcher_map_key](bool on_link_destruction) {
        // We expect |child_view_watcher_map_key| to be assigned by the "link_resolved" closure, but
        // this might not happen if the link is being destroyed before it was resolved.
        FX_DCHECK(child_view_watcher_map_key || on_link_destruction);
        std::scoped_lock lock(ref->mutex_);
        ref->child_view_watcher_map_.erase(*child_view_watcher_map_key);
      },
      dispatcher_holder);

  return ChildLink({
      .parent_viewport_watcher_handle = parent_viewport_watcher_handle,
      .link_handle = link_handle,
      .importer = std::move(importer),
  });
}

LinkSystem::ParentLink LinkSystem::CreateParentLink(
    std::shared_ptr<utils::DispatcherHolder> dispatcher_holder, ViewCreationToken token,
    std::optional<fuchsia::ui::views::ViewIdentityOnCreation> view_identity,
    fidl::InterfaceRequest<ParentViewportWatcher> parent_viewport_watcher,
    TransformHandle child_view_watcher_handle, LinkProtocolErrorCallback error_callback) {
  FX_DCHECK(token.value.is_valid());

  std::shared_ptr<fuchsia::ui::views::ViewRef> view_ref;
  std::optional<fuchsia::ui::views::ViewRefControl> view_ref_control;
  if (view_identity.has_value()) {
    view_ref = std::make_shared<fuchsia::ui::views::ViewRef>(std::move(view_identity->view_ref));
    view_ref_control = std::move(view_identity->view_ref_control);
  }

  auto impl = std::make_shared<ParentViewportWatcherImpl>(
      dispatcher_holder, std::move(parent_viewport_watcher), error_callback);

  ObjectLinker::ExportLink exporter = linker_->CreateExport(
      ParentLinkInfo{.child_view_watcher_handle = child_view_watcher_handle, .view_ref = view_ref},
      std::move(token.value),
      /* error_reporter */ nullptr);

  auto parent_viewport_watcher_map_key = std::make_shared<TransformHandle>();
  auto topology_map_key = std::make_shared<TransformHandle>();
  exporter.Initialize(
      /* link_resolved = */
      [ref = shared_from_this(), impl, parent_viewport_watcher_map_key, topology_map_key,
       child_view_watcher_handle](ChildLinkInfo info) {
        *parent_viewport_watcher_map_key = info.parent_viewport_watcher_handle;
        *topology_map_key = info.link_handle;

        std::scoped_lock lock(ref->mutex_);
        // TODO(fxbug.dev/80603): When the same parent relinks to different children, we might be
        // using an outdated logical_size here. It will be corrected in UpdateLinks(), but we should
        // figure out a way to set the previous ParentViewportWatcherImpl's size here.
        LayoutInfo layout_info;
        layout_info.set_logical_size(info.initial_logical_size);
        layout_info.set_pixel_scale({1, 1});
        impl->UpdateLayoutInfo(std::move(layout_info));

        ref->parent_viewport_watcher_map_[*parent_viewport_watcher_map_key] =
            ParentViewportWatcherData(
                {.impl = impl, .child_link_origin = child_view_watcher_handle});
        // The topology is constructed here, instead of in the link_resolved closure of the
        // ParentLink object, so that its destruction (which depends on the link_handle) can occur
        // on the same endpoint.
        ref->link_topologies_[*topology_map_key] = child_view_watcher_handle;
      },
      /* link_invalidated = */
      [ref = shared_from_this(), impl, parent_viewport_watcher_map_key,
       topology_map_key](bool on_link_destruction) {
        // We expect |parent_viewport_watcher_map_key| and |topology_map_key| to be assigned by the
        // "link_resolved" closure, but this might not happen if the link is being destroyed before
        // it was resolved.
        FX_DCHECK((parent_viewport_watcher_map_key && topology_map_key) || on_link_destruction);
        std::scoped_lock map_lock(ref->mutex_);
        ref->parent_viewport_watcher_map_.erase(*parent_viewport_watcher_map_key);

        ref->link_topologies_.erase(*topology_map_key);
        ref->link_graph_.ReleaseTransform(*topology_map_key);
      },
      dispatcher_holder);

  return ParentLink({.child_view_watcher_handle = child_view_watcher_handle,
                     .exporter = std::move(exporter),
                     .view_ref = std::move(view_ref),
                     .view_ref_control = std::move(view_ref_control)});
}

void LinkSystem::UpdateLinks(const GlobalTopologyData::TopologyVector& global_topology,
                             const std::unordered_set<TransformHandle>& live_handles,
                             const GlobalMatrixVector& global_matrices,
                             const glm::vec2& display_pixel_scale,
                             const UberStruct::InstanceMap& uber_structs) {
  std::scoped_lock lock(mutex_);

  // Since the global topology may not contain every Flatland instance, manually update the
  // ParentViewportStatus of every ParentViewportWatcher.
  for (auto& [graph_handle, parent_viewport_watcher] : parent_viewport_watcher_map_) {
    // The child Flatland instance is connected to the display if it is present in the global
    // topology.
    parent_viewport_watcher.impl->UpdateLinkStatus(
        live_handles.count(parent_viewport_watcher.child_link_origin) > 0
            ? ParentViewportStatus::CONNECTED_TO_DISPLAY
            : ParentViewportStatus::DISCONNECTED_FROM_DISPLAY);
  }

  // ChildViewWatcher has two hanging get methods, GetStatus() and GetViewRef(), whose responses are
  // generated in the loop below.
  for (auto& [link_origin, child_view_watcher] : child_view_watcher_map_) {
    // The ChildViewStatus changes the first time the child presents with a particular parent link.
    // This is indicated by an UberStruct with the |link_origin| as its first TransformHandle in the
    // snapshot.
    //
    // NOTE: This does not mean the child content is actually appears on-screen; it simply informs
    //       the parent that the child has content that is available to present on screen.  This is
    //       intentional; for example, the parent might not want to attach the child to the global
    //       scene graph until it knows the child is ready to present content on screen.
    //
    // NOTE: The LinkSystem can technically "miss" updating the ChildViewStatus for a
    //       particular ChildViewWatcher if the child presents two CreateView() calls before
    //       UpdateLinks() is called, but in that case, the first Link is destroyed, and therefore
    //       its status does not need to be updated anyway.
    auto uber_struct_kv = uber_structs.find(link_origin.GetInstanceId());
    if (uber_struct_kv != uber_structs.end()) {
      const auto& local_topology = uber_struct_kv->second->local_topology;

      // If the local topology doesn't start with the |link_origin|, the child is linked to a
      // different parent now, but the link_invalidated callback to remove this entry has not fired
      // yet.
      if (!local_topology.empty() && local_topology.front().handle == link_origin) {
        child_view_watcher->UpdateLinkStatus(ChildViewStatus::CONTENT_HAS_PRESENTED);
      }
    }

    // As soon as the child view is part of the global topology, update the watcher to send it along
    // to any caller of GetViewRef().  For example, this means that by the time the watcher receives
    // it, the child view will already exist in the view tree, and therefore an attempt to focus it
    // will succeed.
    if (live_handles.count(link_origin) > 0) {
      child_view_watcher->UpdateViewRef();
    }
  }

  std::unordered_map<std::shared_ptr<ParentViewportWatcherImpl>, LayoutInfo> layout_map;
  for (size_t i = 0; i < global_topology.size(); ++i) {
    const auto& handle = global_topology[i];

    // For a particular Link, the ViewportProperties and ParentViewportWatcherImpl both live on the
    // ChildLink's |graph_handle|. They can show up in either order (ViewportProperties before
    // ParentViewportWatcherImpl if the parent Flatland calls Present() first, other way around if
    // the link resolves first), so one being present without another is not a bug.
    auto graph_kv = parent_viewport_watcher_map_.find(handle);
    if (graph_kv != parent_viewport_watcher_map_.end()) {
      auto uber_struct_kv = uber_structs.find(handle.GetInstanceId());
      if (uber_struct_kv != uber_structs.end()) {
        auto properties_kv = uber_struct_kv->second->link_properties.find(handle);
        if (properties_kv != uber_struct_kv->second->link_properties.end() &&
            properties_kv->second.has_logical_size()) {
          const auto pixel_scale = display_pixel_scale * ComputeScale(global_matrices[i]);
          LayoutInfo info;
          info.set_logical_size(properties_kv->second.logical_size());
          info.set_pixel_scale(
              {static_cast<uint32_t>(pixel_scale.x), static_cast<uint32_t>(pixel_scale.y)});

          // A transform handle may have multiple parents, resulting in the same handle appearing
          // in the global topology vector multiple times, with multiple global matrices. We only
          // want to update the LayoutInfo for the instance that has the lowest scale value.
          auto watcher = graph_kv->second.impl;
          if (layout_map.find(watcher) == layout_map.end()) {
            layout_map[watcher] = std::move(info);
          } else {
            const auto& curr_info = layout_map[watcher];
            if (curr_info.pixel_scale().width > info.pixel_scale().width) {
              layout_map[watcher] = std::move(info);
            }
          }
        }
      }
    }
  }

  // Now that we've determined which layout information to associate with a
  // ParentViewportWatcherImpl, we can now update each one.
  for (auto& [watcher, info] : layout_map) {
    watcher->UpdateLayoutInfo(std::move(info));
  }
}

GlobalTopologyData::LinkTopologyMap LinkSystem::GetResolvedTopologyLinks() {
  GlobalTopologyData::LinkTopologyMap copy;

  // Acquire the lock and copy.
  {
    std::scoped_lock lock(mutex_);
    copy = link_topologies_;
  }
  return copy;
}

TransformHandle::InstanceId LinkSystem::GetInstanceId() const { return instance_id_; }

std::unordered_map<TransformHandle, TransformHandle> const
LinkSystem::GetChildViewWatcherToParentViewportWatcherMapping() {
  std::unordered_map<TransformHandle, TransformHandle> mapping;
  for (auto& [handle, data] : parent_viewport_watcher_map_) {
    mapping.try_emplace(data.child_link_origin, handle);
  }
  return mapping;
}

}  // namespace flatland
