// Copyright 2018 The Chromium 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 "services/ws/client_root.h"

#include "components/viz/common/surfaces/surface_info.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "services/ws/client_change.h"
#include "services/ws/client_change_tracker.h"
#include "services/ws/server_window.h"
#include "services/ws/window_service.h"
#include "services/ws/window_tree.h"
#include "ui/aura/env.h"
#include "ui/aura/mus/client_surface_embedder.h"
#include "ui/aura/mus/property_converter.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/dip_util.h"
#include "ui/compositor/property_change_reason.h"

namespace ws {

ClientRoot::ClientRoot(WindowTree* window_tree,
                       aura::Window* window,
                       bool is_top_level)
    : window_tree_(window_tree), window_(window), is_top_level_(is_top_level) {
  window_->AddObserver(this);
  if (window_->GetHost())
    window->GetHost()->AddObserver(this);
  client_surface_embedder_ = std::make_unique<aura::ClientSurfaceEmbedder>(
      window_, is_top_level, gfx::Insets());
  // Ensure there is a valid LocalSurfaceId (if necessary).
  UpdateLocalSurfaceIdIfNecessary();
}

ClientRoot::~ClientRoot() {
  ServerWindow* server_window = ServerWindow::GetMayBeNull(window_);
  window_->RemoveObserver(this);
  if (window_->GetHost())
    window_->GetHost()->RemoveObserver(this);

  viz::HostFrameSinkManager* host_frame_sink_manager =
      window_->env()->context_factory_private()->GetHostFrameSinkManager();
  host_frame_sink_manager->InvalidateFrameSinkId(
      server_window->frame_sink_id());
}

void ClientRoot::SetClientAreaInsets(const gfx::Insets& client_area_insets) {
  if (!is_top_level_)
    return;

  client_surface_embedder_->SetClientAreaInsets(client_area_insets);
}

void ClientRoot::RegisterVizEmbeddingSupport() {
  // This function should only be called once.
  viz::HostFrameSinkManager* host_frame_sink_manager =
      window_->env()->context_factory_private()->GetHostFrameSinkManager();
  viz::FrameSinkId frame_sink_id =
      ServerWindow::GetMayBeNull(window_)->frame_sink_id();
  host_frame_sink_manager->RegisterFrameSinkId(frame_sink_id, this);
  window_->SetEmbedFrameSinkId(frame_sink_id);

  UpdatePrimarySurfaceId();
}

bool ClientRoot::ShouldAssignLocalSurfaceId() {
  // First level embeddings have their LocalSurfaceId assigned by the
  // WindowService. First level embeddings have no embeddings above them.
  if (is_top_level_)
    return true;
  ServerWindow* server_window = ServerWindow::GetMayBeNull(window_);
  return server_window->owning_window_tree() == nullptr;
}

void ClientRoot::UpdateLocalSurfaceIdIfNecessary() {
  if (!ShouldAssignLocalSurfaceId())
    return;

  gfx::Size size_in_pixels =
      ui::ConvertSizeToPixel(window_->layer(), window_->bounds().size());
  ServerWindow* server_window = ServerWindow::GetMayBeNull(window_);
  // It's expected by cc code that any time the size changes a new
  // LocalSurfaceId is used.
  if (last_surface_size_in_pixels_ != size_in_pixels ||
      !server_window->local_surface_id().has_value() ||
      last_device_scale_factor_ != window_->layer()->device_scale_factor()) {
    server_window->set_local_surface_id(
        parent_local_surface_id_allocator_.GenerateId());
    last_surface_size_in_pixels_ = size_in_pixels;
    last_device_scale_factor_ = window_->layer()->device_scale_factor();
  }
}

void ClientRoot::OnLocalSurfaceIdChanged() {
  if (!ShouldAssignLocalSurfaceId())
    HandleBoundsOrScaleFactorChange(window_->bounds());
}

void ClientRoot::AttachChildFrameSinkId(ServerWindow* server_window) {
  DCHECK(server_window->attached_frame_sink_id().is_valid());
  DCHECK(ServerWindow::GetMayBeNull(window_)->frame_sink_id().is_valid());
  viz::HostFrameSinkManager* host_frame_sink_manager =
      window_->env()->context_factory_private()->GetHostFrameSinkManager();
  const viz::FrameSinkId& frame_sink_id =
      server_window->attached_frame_sink_id();
  if (host_frame_sink_manager->IsFrameSinkIdRegistered(frame_sink_id)) {
    host_frame_sink_manager->RegisterFrameSinkHierarchy(
        ServerWindow::GetMayBeNull(window_)->frame_sink_id(), frame_sink_id);
  }
}

void ClientRoot::UnattachChildFrameSinkId(ServerWindow* server_window) {
  DCHECK(server_window->attached_frame_sink_id().is_valid());
  DCHECK(ServerWindow::GetMayBeNull(window_)->frame_sink_id().is_valid());
  viz::HostFrameSinkManager* host_frame_sink_manager =
      window_->env()->context_factory_private()->GetHostFrameSinkManager();
  const viz::FrameSinkId& root_frame_sink_id =
      ServerWindow::GetMayBeNull(window_)->frame_sink_id();
  const viz::FrameSinkId& window_frame_sink_id =
      server_window->attached_frame_sink_id();
  if (host_frame_sink_manager->IsFrameSinkHierarchyRegistered(
          root_frame_sink_id, window_frame_sink_id)) {
    host_frame_sink_manager->UnregisterFrameSinkHierarchy(root_frame_sink_id,
                                                          window_frame_sink_id);
  }
}

void ClientRoot::AttachChildFrameSinkIdRecursive(ServerWindow* server_window) {
  if (server_window->attached_frame_sink_id().is_valid())
    AttachChildFrameSinkId(server_window);

  for (aura::Window* child : server_window->window()->children()) {
    ServerWindow* child_server_window = ServerWindow::GetMayBeNull(child);
    if (child_server_window->owning_window_tree() == window_tree_)
      AttachChildFrameSinkIdRecursive(child_server_window);
  }
}

void ClientRoot::UnattachChildFrameSinkIdRecursive(
    ServerWindow* server_window) {
  if (server_window->attached_frame_sink_id().is_valid())
    UnattachChildFrameSinkId(server_window);

  for (aura::Window* child : server_window->window()->children()) {
    ServerWindow* child_server_window = ServerWindow::GetMayBeNull(child);
    if (child_server_window->owning_window_tree() == window_tree_)
      UnattachChildFrameSinkIdRecursive(child_server_window);
  }
}

void ClientRoot::UpdatePrimarySurfaceId() {
  UpdateLocalSurfaceIdIfNecessary();
  ServerWindow* server_window = ServerWindow::GetMayBeNull(window_);
  if (server_window->local_surface_id().has_value()) {
    client_surface_embedder_->SetPrimarySurfaceId(viz::SurfaceId(
        window_->GetFrameSinkId(), *server_window->local_surface_id()));
    if (fallback_surface_info_) {
      client_surface_embedder_->SetFallbackSurfaceInfo(*fallback_surface_info_);
      fallback_surface_info_.reset();
    }
  }
}

void ClientRoot::CheckForScaleFactorChange() {
  if (!ShouldAssignLocalSurfaceId() ||
      last_device_scale_factor_ == window_->layer()->device_scale_factor()) {
    return;
  }

  HandleBoundsOrScaleFactorChange(is_top_level_ ? window_->GetBoundsInScreen()
                                                : window_->bounds());
}

void ClientRoot::HandleBoundsOrScaleFactorChange(const gfx::Rect& old_bounds) {
  UpdatePrimarySurfaceId();
  client_surface_embedder_->UpdateSizeAndGutters();
  // See comments in WindowTree::SetWindowBoundsImpl() for details on
  // why this always notifies the client.
  window_tree_->window_tree_client_->OnWindowBoundsChanged(
      window_tree_->TransportIdForWindow(window_), old_bounds,
      is_top_level_ ? window_->GetBoundsInScreen() : window_->bounds(),
      ServerWindow::GetMayBeNull(window_)->local_surface_id());
}

void ClientRoot::OnWindowPropertyChanged(aura::Window* window,
                                         const void* key,
                                         intptr_t old) {
  if (window_tree_->property_change_tracker_
          ->IsProcessingPropertyChangeForWindow(window, key)) {
    // Do not send notifications for changes intiated by the client.
    return;
  }
  std::string transport_name;
  std::unique_ptr<std::vector<uint8_t>> transport_value;
  if (window_tree_->window_service()
          ->property_converter()
          ->ConvertPropertyForTransport(window, key, &transport_name,
                                        &transport_value)) {
    base::Optional<std::vector<uint8_t>> transport_value_mojo;
    if (transport_value)
      transport_value_mojo.emplace(std::move(*transport_value));
    window_tree_->window_tree_client_->OnWindowSharedPropertyChanged(
        window_tree_->TransportIdForWindow(window), transport_name,
        transport_value_mojo);
  }
}

void ClientRoot::OnWindowBoundsChanged(aura::Window* window,
                                       const gfx::Rect& old_bounds,
                                       const gfx::Rect& new_bounds,
                                       ui::PropertyChangeReason reason) {
  HandleBoundsOrScaleFactorChange(old_bounds);
}

void ClientRoot::OnWindowAddedToRootWindow(aura::Window* window) {
  DCHECK_EQ(window, window_);
  DCHECK(window->GetHost());
  window->GetHost()->AddObserver(this);
  CheckForScaleFactorChange();
  window_tree_->window_tree_client_->OnWindowDisplayChanged(
      window_tree_->TransportIdForWindow(window),
      window->GetHost()->GetDisplayId());
}

void ClientRoot::OnWindowRemovingFromRootWindow(aura::Window* window,
                                                aura::Window* new_root) {
  DCHECK_EQ(window, window_);
  DCHECK(window->GetHost());
  window->GetHost()->RemoveObserver(this);
}

void ClientRoot::OnHostResized(aura::WindowTreeHost* host) {
  // This function is also called when the device-scale-factor changes too.
  CheckForScaleFactorChange();
}

void ClientRoot::OnFirstSurfaceActivation(
    const viz::SurfaceInfo& surface_info) {
  ServerWindow* server_window = ServerWindow::GetMayBeNull(window_);
  if (server_window->local_surface_id().has_value()) {
    DCHECK(!fallback_surface_info_);
    if (!client_surface_embedder_->HasPrimarySurfaceId())
      UpdatePrimarySurfaceId();
    client_surface_embedder_->SetFallbackSurfaceInfo(surface_info);
  } else {
    fallback_surface_info_ = std::make_unique<viz::SurfaceInfo>(surface_info);
  }
  if (!window_tree_->client_name().empty()) {
    // OnFirstSurfaceActivation() should only be called after
    // AttachCompositorFrameSink().
    DCHECK(server_window->attached_compositor_frame_sink());
    window_tree_->window_service()->OnFirstSurfaceActivation(
        window_tree_->client_name());
  }
}

void ClientRoot::OnFrameTokenChanged(uint32_t frame_token) {
  // TODO: this needs to call through to WindowTreeClient.
  // https://crbug.com/848022.
}

}  // namespace ws
