// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/accessibility/autoclick_test_utils.h"

#include "ash/accessibility/autoclick/autoclick_controller.h"
#include "ash/constants/ash_pref_names.h"
#include "ash/public/cpp/accessibility_controller_enums.h"
#include "ash/shell.h"
#include "ash/system/accessibility/autoclick_menu_bubble_controller.h"
#include "ash/system/accessibility/autoclick_menu_view.h"
#include "base/check_op.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "chrome/browser/ash/accessibility/accessibility_manager.h"
#include "chrome/browser/ash/accessibility/accessibility_test_utils.h"
#include "chrome/browser/ash/accessibility/automation_test_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/extension_constants.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h"
#include "extensions/browser/browsertest_util.h"
#include "extensions/browser/extension_host_test_helper.h"
#include "extensions/browser/extension_registry_test_helper.h"
#include "ui/events/test/event_generator.h"

namespace {
const int kDefaultDelay = 5;
}  // namespace

namespace ash {

AutoclickTestUtils::AutoclickTestUtils(Profile* profile) {
  CHECK_EQ(false, AccessibilityManager::Get()->IsAutoclickEnabled());
  profile_ = profile;
  console_observer_ = std::make_unique<ExtensionConsoleErrorObserver>(
      profile_, extension_misc::kAccessibilityCommonExtensionId);

  SetAutoclickDelayMs(kDefaultDelay);

  pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>();
  pref_change_registrar_->Init(profile_->GetPrefs());
  pref_change_registrar_->Add(
      prefs::kAccessibilityAutoclickEventType,
      base::BindRepeating(&AutoclickTestUtils::OnEventTypePrefChanged,
                          GetWeakPtr()));

  automation_utils_ = std::make_unique<AutomationTestUtils>(
      extension_misc::kAccessibilityCommonExtensionId);
}

AutoclickTestUtils::~AutoclickTestUtils() {
  pref_change_registrar_.reset();
}

void AutoclickTestUtils::LoadAutoclick(bool install_automation_utils) {
  extensions::ExtensionHostTestHelper host_helper(
      profile_, extension_misc::kAccessibilityCommonExtensionId);
  extensions::ExtensionRegistryTestHelper observer(
      extension_misc::kAccessibilityCommonExtensionId, profile_);
  AccessibilityManager::Get()->EnableAutoclick(true);
  Shell::Get()
      ->autoclick_controller()
      ->GetMenuBubbleControllerForTesting()
      ->SetAnimateForTesting(false);
  if (observer.WaitForManifestVersion() == 3) {
    observer.WaitForServiceWorkerStart();
  } else {
    host_helper.WaitForHostCompletedFirstLoad();
  }

  WaitForAutoclickReady();
  if (install_automation_utils) {
    automation_utils_->SetUpTestSupport();
  }
}

void AutoclickTestUtils::SetAutoclickDelayMs(int ms) {
  profile_->GetPrefs()->SetInteger(prefs::kAccessibilityAutoclickDelayMs, ms);
  profile_->GetPrefs()->CommitPendingWrite();
}

void AutoclickTestUtils::SetAutoclickEventTypeWithHover(
    ui::test::EventGenerator* generator,
    AutoclickEventType type) {
  // Check if we already have the right type selected.
  if (profile_->GetPrefs()->GetInteger(
          prefs::kAccessibilityAutoclickEventType) == static_cast<int>(type)) {
    return;
  }

  // Change the Autoclick delay to a value we know will work for this method
  // (in case it was set to a very large value before this method was called).
  int old_delay =
      profile_->GetPrefs()->GetInteger(prefs::kAccessibilityAutoclickDelayMs);
  SetAutoclickDelayMs(kDefaultDelay);

  // Find the menu button.
  AutoclickMenuView::ButtonId button_id;
  switch (type) {
    case AutoclickEventType::kLeftClick:
      button_id = AutoclickMenuView::ButtonId::kLeftClick;
      break;
    case AutoclickEventType::kRightClick:
      button_id = AutoclickMenuView::ButtonId::kRightClick;
      break;
    case AutoclickEventType::kDoubleClick:
      button_id = AutoclickMenuView::ButtonId::kDoubleClick;
      break;
    case AutoclickEventType::kDragAndDrop:
      button_id = AutoclickMenuView::ButtonId::kDragAndDrop;
      break;
    case AutoclickEventType::kScroll:
      button_id = AutoclickMenuView::ButtonId::kScroll;
      break;
    case AutoclickEventType::kNoAction:
      button_id = AutoclickMenuView::ButtonId::kPause;
      break;
  }
  AutoclickMenuView* menu_view = Shell::Get()
                                     ->autoclick_controller()
                                     ->GetMenuBubbleControllerForTesting()
                                     ->menu_view_;
  CHECK_NE(nullptr, menu_view);
  auto* button_view = menu_view->GetViewByID(static_cast<int>(button_id));
  CHECK_NE(nullptr, button_view);

  // Hover over it.
  const gfx::Rect bounds = button_view->GetBoundsInScreen();
  generator->MoveMouseTo(bounds.CenterPoint());

  // Wait for the pref change, indicating the button was pressed.
  base::RunLoop runner;
  pref_change_waiter_ = runner.QuitClosure();
  runner.Run();

  // Restore the delay to its previous value.
  SetAutoclickDelayMs(old_delay);
}

void AutoclickTestUtils::WaitForPageLoad(const std::string& url) {
  automation_utils_->WaitForPageLoad(url);
}

void AutoclickTestUtils::WaitForTextSelectionChangedEvent() {
  automation_utils_->WaitForTextSelectionChangedEvent();
}

void AutoclickTestUtils::HoverOverHtmlElement(
    ui::test::EventGenerator* generator,
    const std::string& name,
    const std::string& role) {
  const gfx::Rect bounds = automation_utils_->GetNodeBoundsInRoot(name, role);
  generator->MoveMouseTo(bounds.CenterPoint());
}

void AutoclickTestUtils::ObserveFocusRings() {
  // Create a callback for the focus ring observer.
  AccessibilityManager::Get()->SetFocusRingObserverForTest(base::BindRepeating(
      &AutoclickTestUtils::OnFocusRingChanged, GetWeakPtr()));
}

void AutoclickTestUtils::WaitForFocusRingChanged() {
  loop_runner_ = std::make_unique<base::RunLoop>();
  loop_runner_->Run();
}

gfx::Rect AutoclickTestUtils::GetNodeBoundsInRoot(const std::string& name,
                                                  const std::string& role) {
  return automation_utils_->GetNodeBoundsInRoot(name, role);
}

gfx::Rect AutoclickTestUtils::GetBoundsForNodeInRootByClassName(
    const std::string& class_name) {
  return automation_utils_->GetBoundsForNodeInRootByClassName(class_name);
}

void AutoclickTestUtils::WaitForAutoclickReady() {
  base::ScopedAllowBlockingForTesting allow_blocking;
  std::string script = base::StringPrintf(R"JS(
    (async function() {
      globalThis.accessibilityCommon.setFeatureLoadCallbackForTest('autoclick',
          () => {
            chrome.test.sendScriptResult('ready');
          });
    })();
  )JS");
  base::Value result =
      extensions::browsertest_util::ExecuteScriptInBackgroundPage(
          profile_, extension_misc::kAccessibilityCommonExtensionId, script);
  ASSERT_EQ("ready", result);
}

void AutoclickTestUtils::OnEventTypePrefChanged() {
  if (pref_change_waiter_) {
    std::move(pref_change_waiter_).Run();
  }
}

void AutoclickTestUtils::OnFocusRingChanged() {
  if (loop_runner_ && loop_runner_->running()) {
    loop_runner_->Quit();
  }
}

base::WeakPtr<AutoclickTestUtils> AutoclickTestUtils::GetWeakPtr() {
  return weak_ptr_factory_.GetWeakPtr();
}

}  // namespace ash
