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

#include <memory>

#include "base/run_loop.h"
#include "services/service_manager/public/cpp/connector.h"
#include "services/service_manager/public/cpp/test/test_connector_factory.h"
#include "services/ws/public/cpp/host/gpu_interface_provider.h"
#include "services/ws/public/mojom/constants.mojom.h"
#include "services/ws/public/mojom/window_tree.mojom.h"
#include "services/ws/window_service_test_setup.h"
#include "services/ws/window_tree.h"
#include "services/ws/window_tree_test_helper.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ws {
namespace {

// Used as callback from ScheduleEmbed().
void ScheduleEmbedCallback(base::UnguessableToken* result_token,
                           const base::UnguessableToken& actual_token) {
  *result_token = actual_token;
}

}  // namespace

TEST(WindowServiceTest, DeleteWithClients) {
  // Use |test_setup| to configure aura and other state.
  WindowServiceTestSetup test_setup;

  // Create another WindowService.
  TestWindowServiceDelegate test_window_service_delegate;
  std::unique_ptr<WindowService> window_service_ptr =
      std::make_unique<WindowService>(&test_window_service_delegate, nullptr,
                                      test_setup.focus_controller());
  WindowService* window_service = window_service_ptr.get();
  std::unique_ptr<service_manager::TestConnectorFactory> factory =
      service_manager::TestConnectorFactory::CreateForUniqueService(
          std::move(window_service_ptr));
  std::unique_ptr<service_manager::Connector> connector =
      factory->CreateConnector();

  // Connect to |window_service| and ask for a new WindowTree.
  mojom::WindowTreeFactoryPtr window_tree_factory;
  connector->BindInterface(mojom::kServiceName, &window_tree_factory);
  mojom::WindowTreePtr window_tree;
  mojom::WindowTreeClientPtr client;
  mojom::WindowTreeClientRequest client_request = MakeRequest(&client);
  window_tree_factory->CreateWindowTree(MakeRequest(&window_tree),
                                        std::move(client));

  // Use FlushForTesting() to ensure WindowService processes the request.
  window_tree_factory.FlushForTesting();

  // There should be at least one WindowTree.
  EXPECT_FALSE(window_service->window_trees().empty());

  // Destroying the |window_service| should remove all the WindowTrees and
  // ensure a DCHECK isn't hit in ~WindowTree.
}

// Test client ids assigned to window trees that connect to the window service.
TEST(WindowServiceTest, ClientIds) {
  // Use |test_setup| to configure aura and other state.
  WindowServiceTestSetup test_setup;

  // Create another WindowService.
  TestWindowServiceDelegate test_window_service_delegate;
  WindowService window_service(&test_window_service_delegate, nullptr,
                               test_setup.focus_controller());

  // The first window tree should have the initial client id.
  auto tree = window_service.CreateWindowTree(nullptr);
  EXPECT_EQ(kInitialClientId, WindowTreeTestHelper(tree.get()).client_id());

  // The second window tree should have an incremented client id.
  tree = window_service.CreateWindowTree(nullptr);
  EXPECT_EQ(kInitialClientId + 1, WindowTreeTestHelper(tree.get()).client_id());
}

// Test client ids assigned to window trees in the decrementing mode.
TEST(WindowServiceTest, ClientIdsDecrement) {
  // Use |test_setup| to configure aura and other state.
  WindowServiceTestSetup test_setup;

  // Create another WindowService that decrements window ids.
  const bool decrement = true;
  TestWindowServiceDelegate test_window_service_delegate;
  WindowService window_service(&test_window_service_delegate, nullptr,
                               test_setup.focus_controller(), decrement);

  // The first window tree should have the initial decrementing client id.
  auto tree = window_service.CreateWindowTree(nullptr);
  EXPECT_EQ(kInitialClientIdDecrement,
            WindowTreeTestHelper(tree.get()).client_id());

  // The second window tree should have a decremented client id.
  tree = window_service.CreateWindowTree(nullptr);
  EXPECT_EQ(kInitialClientIdDecrement - 1,
            WindowTreeTestHelper(tree.get()).client_id());
}

TEST(WindowServiceTest, ScheduleEmbedForExistingClientUsingLocalWindow) {
  WindowServiceTestSetup setup;
  // Schedule an embed in the tree created by |setup|.
  base::UnguessableToken token;
  const uint32_t window_id_in_child = 149;
  setup.window_tree_test_helper()
      ->window_tree()
      ->ScheduleEmbedForExistingClient(
          window_id_in_child, base::BindOnce(&ScheduleEmbedCallback, &token));
  EXPECT_FALSE(token.is_empty());

  // Create a window that will serve as the parent for the remote window and
  // complete the embedding.
  std::unique_ptr<aura::Window> local_window =
      std::make_unique<aura::Window>(nullptr);
  local_window->Init(ui::LAYER_NOT_DRAWN);
  ASSERT_TRUE(setup.service()->CompleteScheduleEmbedForExistingClient(
      local_window.get(), token, /* embed_flags */ 0));
  EXPECT_TRUE(WindowService::HasRemoteClient(local_window.get()));
}

TEST(WindowServiceTest,
     ScheduleEmbedForExistingClientUsingLocalWindowResetOnTreeDeleted) {
  WindowServiceTestSetup setup;
  TestWindowTreeClient window_tree_client2;
  std::unique_ptr<WindowTree> window_tree2 =
      setup.service()->CreateWindowTree(&window_tree_client2);
  window_tree2->InitFromFactory();

  // Schedule an embed in |window_tree2|.
  base::UnguessableToken token;
  const uint32_t window_id_in_child = 212;
  WindowTreeTestHelper(window_tree2.get())
      .window_tree()
      ->ScheduleEmbedForExistingClient(
          window_id_in_child, base::BindOnce(&ScheduleEmbedCallback, &token));
  EXPECT_FALSE(token.is_empty());

  // Create a window that will serve as the parent for the remote window and
  // complete the embedding.
  std::unique_ptr<aura::Window> local_window =
      std::make_unique<aura::Window>(nullptr);
  local_window->Init(ui::LAYER_NOT_DRAWN);
  ASSERT_TRUE(setup.service()->CompleteScheduleEmbedForExistingClient(
      local_window.get(), token, /* embed_flags */ 0));
  EXPECT_TRUE(WindowService::HasRemoteClient(local_window.get()));

  // Deleting |window_tree2| should remove the remote client.
  window_tree2.reset();
  EXPECT_FALSE(WindowService::HasRemoteClient(local_window.get()));
}

}  // namespace ws
