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

#include "base/bind.h"
#include "services/ws/embedding.h"
#include "services/ws/event_queue.h"
#include "services/ws/event_queue_test_helper.h"
#include "services/ws/public/cpp/host/gpu_interface_provider.h"
#include "services/ws/window_service.h"
#include "services/ws/window_tree.h"
#include "services/ws/window_tree_binding.h"
#include "ui/aura/test/event_generator_delegate_aura.h"
#include "ui/aura/window_tree_host.h"
#include "ui/display/screen.h"
#include "ui/events/event_target_iterator.h"
#include "ui/gl/test/gl_surface_test_support.h"
#include "ui/wm/core/base_focus_rules.h"
#include "ui/wm/core/capture_controller.h"
#include "ui/wm/public/activation_client.h"

namespace ws {
namespace {

class TestFocusRules : public wm::BaseFocusRules {
 public:
  TestFocusRules() = default;
  ~TestFocusRules() override = default;

  // wm::BaseFocusRules:
  bool SupportsChildActivation(const aura::Window* window) const override {
    return window == window->GetRootWindow();
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(TestFocusRules);
};

// An EventSource that mimics AshWindowTreeHostPlatform's EventQueue usage.
class EventSourceWithQueue : public ui::EventSource {
 public:
  explicit EventSourceWithQueue(WindowServiceTestSetup* test_setup,
                                aura::Window* root)
      : test_setup_(test_setup), root_(root) {}
  ~EventSourceWithQueue() override = default;

  // ui::EventSource:
  ui::EventSink* GetEventSink() override {
    return root_->GetHost()->GetEventSink();
  }
  ui::EventDispatchDetails DeliverEventToSink(ui::Event* event) override {
    auto* queue = test_setup_->service()->event_queue();
    // Queue the event if needed, or deliver it directly to the sink.
    auto result = queue->DeliverOrQueueEvent(root_->GetHost(), event);
    if (test_setup_->ack_events_immediately() &&
        EventQueueTestHelper(queue).HasInFlightEvent()) {
      EventQueueTestHelper(queue).AckInFlightEvent();
    }

    return result.value_or(ui::EventDispatchDetails());
  }

 private:
  WindowServiceTestSetup* test_setup_;
  aura::Window* root_;

  DISALLOW_COPY_AND_ASSIGN(EventSourceWithQueue);
};

// EventGeneratorDelegate implementation for mus.
class EventGeneratorDelegateWs : public aura::test::EventGeneratorDelegateAura {
 public:
  explicit EventGeneratorDelegateWs(WindowServiceTestSetup* test_setup,
                                    aura::Window* root)
      : root_(root), event_source_(test_setup, root) {}
  ~EventGeneratorDelegateWs() override = default;

  // EventGeneratorDelegateAura:
  ui::EventTarget* GetTargetAt(const gfx::Point& location) override {
    return root_;
  }
  ui::EventSource* GetEventSource(ui::EventTarget* target) override {
    return target == root_ ? &event_source_
                           : EventGeneratorDelegateAura::GetEventSource(target);
  }
  gfx::Point CenterOfTarget(const ui::EventTarget* target) const override {
    if (target != root_)
      return EventGeneratorDelegateAura::CenterOfTarget(target);
    return display::Screen::GetScreen()
        ->GetPrimaryDisplay()
        .bounds()
        .CenterPoint();
  }
  void ConvertPointFromTarget(const ui::EventTarget* target,
                              gfx::Point* point) const override {
    if (target != root_)
      EventGeneratorDelegateAura::ConvertPointFromTarget(target, point);
  }
  void ConvertPointToTarget(const ui::EventTarget* target,
                            gfx::Point* point) const override {
    if (target != root_)
      EventGeneratorDelegateAura::ConvertPointToTarget(target, point);
  }
  void ConvertPointFromHost(const ui::EventTarget* hosted_target,
                            gfx::Point* point) const override {
    if (hosted_target != root_)
      EventGeneratorDelegateAura::ConvertPointFromHost(hosted_target, point);
  }

 private:
  aura::Window* root_;
  EventSourceWithQueue event_source_;

  DISALLOW_COPY_AND_ASSIGN(EventGeneratorDelegateWs);
};

std::unique_ptr<ui::test::EventGeneratorDelegate> CreateEventGeneratorDelegate(
    WindowServiceTestSetup* test_setup,
    ui::test::EventGenerator* owner,
    aura::Window* root_window,
    aura::Window* window) {
  DCHECK(root_window);
  DCHECK(root_window->GetHost());
  return std::make_unique<EventGeneratorDelegateWs>(test_setup, root_window);
}

}  // namespace

WindowServiceTestSetup::WindowServiceTestSetup()
    // FocusController takes ownership of TestFocusRules.
    : focus_controller_(new TestFocusRules()) {
  DCHECK_EQ(gl::kGLImplementationNone, gl::GetGLImplementation());
  gl::GLSurfaceTestSupport::InitializeOneOff();

  ui::ContextFactory* context_factory = nullptr;
  ui::ContextFactoryPrivate* context_factory_private = nullptr;
  const bool enable_pixel_output = false;
  ui::InitializeContextFactoryForTests(enable_pixel_output, &context_factory,
                                       &context_factory_private);
  aura_test_helper_.SetUp(context_factory, context_factory_private);
  scoped_capture_client_ = std::make_unique<wm::ScopedCaptureClient>(
      aura_test_helper_.root_window());
  service_ =
      std::make_unique<WindowService>(&delegate_, nullptr, focus_controller());
  aura::client::SetFocusClient(root(), focus_controller());
  wm::SetActivationClient(root(), focus_controller());
  delegate_.set_top_level_parent(aura_test_helper_.root_window());

  window_tree_ = service_->CreateWindowTree(&window_tree_client_);
  window_tree_->InitFromFactory();
  window_tree_test_helper_ =
      std::make_unique<WindowTreeTestHelper>(window_tree_.get());

  ui::test::EventGeneratorDelegate::SetFactoryFunction(
      base::BindRepeating(&CreateEventGeneratorDelegate, this));
}

WindowServiceTestSetup::~WindowServiceTestSetup() {
  window_tree_test_helper_.reset();
  window_tree_.reset();
  service_.reset();
  scoped_capture_client_.reset();
  aura::client::SetFocusClient(root(), nullptr);
  aura_test_helper_.TearDown();
  ui::TerminateContextFactoryForTests();
  gl::GLSurfaceTestSupport::ShutdownGL();
  ui::test::EventGeneratorDelegate::SetFactoryFunction(
      ui::test::EventGeneratorDelegate::FactoryFunction());
}

std::unique_ptr<EmbeddingHelper> WindowServiceTestSetup::CreateEmbedding(
    aura::Window* embed_root,
    uint32_t flags) {
  auto embedding_helper = std::make_unique<EmbeddingHelper>();
  embedding_helper->embedding = window_tree_test_helper_->Embed(
      embed_root, nullptr, &embedding_helper->window_tree_client, flags);
  if (!embedding_helper->embedding)
    return nullptr;
  embedding_helper->window_tree = embedding_helper->embedding->embedded_tree();
  embedding_helper->window_tree_test_helper =
      std::make_unique<WindowTreeTestHelper>(embedding_helper->window_tree);
  embedding_helper->parent_window_tree =
      embedding_helper->embedding->embedding_tree();
  return embedding_helper;
}

EmbeddingHelper::EmbeddingHelper() = default;

EmbeddingHelper::~EmbeddingHelper() {
  if (!embedding)
    return;

  WindowTreeTestHelper(parent_window_tree).DestroyEmbedding(embedding);
}

}  // namespace ws
