// Copyright (c) 2012 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 "ui/aura/test/aura_test_helper.h"

#include "base/bind.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "ui/aura/client/default_capture_client.h"
#include "ui/aura/env.h"
#include "ui/aura/input_state_lookup.h"
#include "ui/aura/test/env_test_helper.h"
#include "ui/aura/test/event_generator_delegate_aura.h"
#include "ui/aura/test/test_focus_client.h"
#include "ui/aura/test/test_screen.h"
#include "ui/aura/test/test_window_parenting_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_targeter.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/ime/init/input_method_factory.h"
#include "ui/base/ime/init/input_method_initializer.h"
#include "ui/compositor/compositor.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/compositor/test/test_context_factories.h"
#include "ui/display/screen.h"
#include "ui/wm/core/default_activation_client.h"
#include "ui/wm/core/default_screen_position_client.h"

#if defined(OS_LINUX) || defined(OS_CHROMEOS)
#include "ui/platform_window/common/platform_window_defaults.h"  // nogncheck
#endif

#if defined(OS_WIN)
#include "base/sequenced_task_runner.h"
#include "ui/aura/native_window_occlusion_tracker_win.h"
#endif

#if defined(USE_X11)
#include "ui/base/x/x11_util.h"  // nogncheck
#endif

#if defined(USE_OZONE)
#include "ui/events/ozone/events_ozone.h"
#endif

#if defined(OS_FUCHSIA)
#include "ui/platform_window/platform_window_init_properties.h"
#endif

namespace aura {
namespace test {
namespace {

AuraTestHelper* g_instance = nullptr;

}  // namespace

AuraTestHelper::AuraTestHelper(ui::ContextFactory* context_factory,
                               bool disable_animations) {
  DCHECK(!g_instance);
  g_instance = this;

#if defined(OS_LINUX) || defined(OS_CHROMEOS)
  ui::test::EnableTestConfigForPlatformWindows();
#endif

#if defined(USE_OZONE) && BUILDFLAG(IS_CHROMEOS_ASH)
  ui::DisableNativeUiEventDispatchForTest();
#endif

#if defined(OS_FUCHSIA)
  ui::PlatformWindowInitProperties::allow_null_view_token_for_test = true;
#endif

  ui::InitializeInputMethodForTesting();

  ui::test::EventGeneratorDelegate::SetFactoryFunction(
      base::BindRepeating(&EventGeneratorDelegateAura::Create));

  if (disable_animations) {
    zero_duration_mode_ =
        std::make_unique<ui::ScopedAnimationDurationScaleMode>(
            ui::ScopedAnimationDurationScaleMode::ZERO_DURATION);
  }

  // Some tests suites create Env globally.
  if (Env::HasInstance())
    context_factory_to_restore_ = Env::GetInstance()->context_factory();
  else
    env_ = Env::CreateInstance();
  Env* env = GetEnv();

  if (!context_factory) {
    context_factories_ = std::make_unique<ui::TestContextFactories>(false);
    context_factory = context_factories_->GetContextFactory();
  }
  env->set_context_factory(context_factory);

  // Reset aura::Env to eliminate test dependency (https://crbug.com/586514).
  EnvTestHelper env_helper(env);
  env_helper.ResetEnvForTesting();
  // Unit tests generally don't want to query the system, rather use the state
  // from RootWindow.
  env_helper.SetInputStateLookup(nullptr);
  env_helper.ResetEventState();

  // This must be reset before creating TestScreen, which sets up the display
  // scale factor for this test iteration.
  display::Display::ResetForceDeviceScaleFactorForTesting();
}

AuraTestHelper::~AuraTestHelper() {
  if (g_instance)
    TearDown();
}

// static
AuraTestHelper* AuraTestHelper::GetInstance() {
  return g_instance;
}

void AuraTestHelper::SetUp() {
  display::Screen* screen = display::Screen::GetScreen();
  gfx::Size host_size(screen ? screen->GetPrimaryDisplay().GetSizeInPixel()
                             : kDefaultHostSize);
  test_screen_.reset(TestScreen::Create(host_size));
  // TODO(pkasting): Seems like we should either always set the screen instance,
  // or not create the screen/host if the test already has one; it doesn't make
  // a lot of sense to me to potentially have multiple screens/hosts/etc. alive
  // and be interacting with both depending on what accessors you use.
  if (!screen)
    display::Screen::SetScreenInstance(test_screen_.get());

  host_.reset(test_screen_->CreateHostForPrimaryDisplay());
  host_->window()->SetEventTargeter(std::make_unique<WindowTargeter>());
  host_->SetBoundsInPixels(gfx::Rect(host_size));

  Window* root_window = GetContext();
  new wm::DefaultActivationClient(root_window);  // Manages own lifetime.
  focus_client_ = std::make_unique<TestFocusClient>(root_window);
  capture_client_ = std::make_unique<client::DefaultCaptureClient>(root_window);
  parenting_client_ = std::make_unique<TestWindowParentingClient>(root_window);
  screen_position_client_ =
      std::make_unique<wm::DefaultScreenPositionClient>(root_window);

  root_window->Show();
}

void AuraTestHelper::TearDown() {
  g_instance = nullptr;

  if (test_screen_ && (display::Screen::GetScreen() == GetTestScreen()))
    display::Screen::SetScreenInstance(nullptr);

  if (!env_)
    Env::GetInstance()->set_context_factory(context_factory_to_restore_);

  ui::test::EventGeneratorDelegate::SetFactoryFunction(
      ui::test::EventGeneratorDelegate::FactoryFunction());

  ui::ShutdownInputMethodForTesting();

  // Destroy all owned objects to prevent tests from depending on their state
  // after this returns.
  screen_position_client_.reset();
  parenting_client_.reset();
  capture_client_.reset();
  focus_client_.reset();
  host_.reset();
  test_screen_.reset();
  context_factories_.reset();
  env_.reset();
  zero_duration_mode_.reset();
  wm_state_.reset();

#if defined(OS_WIN)
  // TODO(pkasting): This code doesn't really belong here.
  // NativeWindowOcclusionTrackerWin is created on demand by various tests, must
  // be torn down before the TaskEnvironment (which our owner is responsible
  // for), and must be torn down after all Windows (so, after e.g. |host_|).
  // Ideally, some specific class would create it and manage its lifetime,
  // guaranteeing the above.
  NativeWindowOcclusionTrackerWin::DeleteInstanceForTesting();
#endif
}

void AuraTestHelper::RunAllPendingInMessageLoop() {
  // TODO(jbates) crbug.com/134753 Find quitters of this RunLoop and have them
  //              use run_loop.QuitClosure().
  base::RunLoop run_loop;
  run_loop.RunUntilIdle();
}

Window* AuraTestHelper::GetContext() {
  return host_ ? host_->window() : nullptr;
}

WindowTreeHost* AuraTestHelper::GetHost() {
  return host_.get();
}

TestScreen* AuraTestHelper::GetTestScreen() {
  return test_screen_.get();
}

client::FocusClient* AuraTestHelper::GetFocusClient() {
  return focus_client_.get();
}

client::CaptureClient* AuraTestHelper::GetCaptureClient() {
  return capture_client_.get();
}

constexpr gfx::Size AuraTestHelper::kDefaultHostSize;

Env* AuraTestHelper::GetEnv() {
  if (env_)
    return env_.get();
  return Env::HasInstance() ? Env::GetInstance() : nullptr;
}

ui::ContextFactory* AuraTestHelper::GetContextFactory() {
  return GetEnv()->context_factory();
}

}  // namespace test
}  // namespace aura
