// 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 "chrome/browser/accessibility/accessibility_extension_api.h"

#include <stddef.h>
#include <memory>
#include <set>
#include <vector>

#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/strings/string_number_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/api/tabs/tabs_constants.h"
#include "chrome/browser/extensions/chrome_extension_function_details.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/api/accessibility_private.h"
#include "chrome/common/extensions/extension_constants.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "components/infobars/core/infobar.h"
#include "content/public/browser/browser_accessibility_state.h"
#include "content/public/common/service_manager_connection.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_system.h"
#include "extensions/common/error_utils.h"
#include "extensions/common/image_util.h"
#include "extensions/common/manifest_handlers/background_info.h"
#include "services/service_manager/public/cpp/connector.h"
#include "ui/events/base_event_utils.h"
#include "ui/events/keycodes/keyboard_codes.h"

#if defined(OS_CHROMEOS)
#include "ash/public/interfaces/accessibility_focus_ring_controller.mojom.h"
#include "ash/public/interfaces/constants.mojom.h"
#include "ash/public/interfaces/event_rewriter_controller.mojom.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_helper_bridge.h"
#include "services/ws/public/mojom/constants.mojom.h"
#include "services/ws/public/mojom/event_injector.mojom.h"
#include "ui/base/ui_base_features.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#endif

namespace accessibility_private = extensions::api::accessibility_private;

namespace {

const char kErrorNotSupported[] = "This API is not supported on this platform.";

#if defined(OS_CHROMEOS)
constexpr int kBackButtonWidth = 45;
constexpr int kBackButtonHeight = 45;

ash::mojom::AccessibilityControllerPtr GetAccessibilityController() {
  // Connect to the accessibility mojo interface in ash.
  ash::mojom::AccessibilityControllerPtr accessibility_controller;
  content::ServiceManagerConnection::GetForProcess()
      ->GetConnector()
      ->BindInterface(ash::mojom::kServiceName, &accessibility_controller);
  return accessibility_controller;
}
#endif

}  // namespace

ExtensionFunction::ResponseAction
AccessibilityPrivateSetNativeAccessibilityEnabledFunction::Run() {
  bool enabled = false;
  EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
  if (enabled) {
    content::BrowserAccessibilityState::GetInstance()->
        EnableAccessibility();
  } else {
    content::BrowserAccessibilityState::GetInstance()->
        DisableAccessibility();
  }
  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
AccessibilityPrivateSetFocusRingsFunction::Run() {
#if defined(OS_CHROMEOS)
  std::unique_ptr<accessibility_private::SetFocusRings::Params> params(
      accessibility_private::SetFocusRings::Params::Create(*args_));
  EXTENSION_FUNCTION_VALIDATE(params);

  auto* accessibility_manager = chromeos::AccessibilityManager::Get();

  for (const accessibility_private::FocusRingInfo& focus_ring_info :
       params->focus_rings) {
    ash::mojom::FocusRingPtr focus_ring_ptr = ash::mojom::FocusRing::New();
    focus_ring_ptr->behavior =
        ash::mojom::FocusRingBehavior::PERSIST_FOCUS_RING;

    // Convert the given rects into gfx::Rect objects.
    for (const accessibility_private::ScreenRect& rect :
         focus_ring_info.rects) {
      focus_ring_ptr->rects_in_screen.push_back(
          gfx::Rect(rect.left, rect.top, rect.width, rect.height));
    }

    const std::string id = accessibility_manager->GetFocusRingId(
        extension_id(), focus_ring_info.id ? *(focus_ring_info.id) : "");

    if (!extensions::image_util::ParseHexColorString(
            focus_ring_info.color, &(focus_ring_ptr->color))) {
      return RespondNow(Error("Could not parse hex color"));
    }

    if (focus_ring_info.secondary_color) {
      if (!extensions::image_util::ParseHexColorString(
              *(focus_ring_info.secondary_color),
              &(focus_ring_ptr->secondary_color))) {
        return RespondNow(Error("Could not parse secondary hex color"));
      }
    }

    switch (focus_ring_info.type) {
      case accessibility_private::FOCUS_TYPE_SOLID:
        focus_ring_ptr->type = ash::mojom::FocusRingType::SOLID;
        break;
      case accessibility_private::FOCUS_TYPE_DASHED:
        focus_ring_ptr->type = ash::mojom::FocusRingType::DASHED;
        break;
      case accessibility_private::FOCUS_TYPE_GLOW:
        focus_ring_ptr->type = ash::mojom::FocusRingType::GLOW;
        break;
      default:
        NOTREACHED();
    }

    // Update the touch exploration controller so that synthesized touch events
    // are anchored within the focused object.
    // NOTE: The final anchor point will be determined by the first rect of the
    // final focus ring.
    if (!focus_ring_ptr->rects_in_screen.empty()) {
      accessibility_manager->SetTouchAccessibilityAnchorPoint(
          focus_ring_ptr->rects_in_screen[0].CenterPoint());
    }

    // Set the focus ring.
    accessibility_manager->SetFocusRing(id, std::move(focus_ring_ptr));
  }

  return RespondNow(NoArguments());
#else
  return RespondNow(Error(kErrorNotSupported));
#endif  // defined(OS_CHROMEOS)
}

ExtensionFunction::ResponseAction
AccessibilityPrivateSetHighlightsFunction::Run() {
#if defined(OS_CHROMEOS)
  std::unique_ptr<accessibility_private::SetHighlights::Params> params(
      accessibility_private::SetHighlights::Params::Create(*args_));
  EXTENSION_FUNCTION_VALIDATE(params);

  std::vector<gfx::Rect> rects;
  for (const accessibility_private::ScreenRect& rect : params->rects) {
    rects.push_back(gfx::Rect(rect.left, rect.top, rect.width, rect.height));
  }

  SkColor color;
  if (!extensions::image_util::ParseHexColorString(params->color, &color))
    return RespondNow(Error("Could not parse hex color"));

  // Set the highlights to cover all of these rects.
  chromeos::AccessibilityManager::Get()->SetHighlights(rects, color);

  return RespondNow(NoArguments());
#endif  // defined(OS_CHROMEOS)

  return RespondNow(Error(kErrorNotSupported));
}

ExtensionFunction::ResponseAction
AccessibilityPrivateSetKeyboardListenerFunction::Run() {
  ChromeExtensionFunctionDetails details(this);
  CHECK(extension());

#if defined(OS_CHROMEOS)
  bool enabled;
  bool capture;
  EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
  EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &capture));

  chromeos::AccessibilityManager* manager =
      chromeos::AccessibilityManager::Get();

  const std::string current_id = manager->keyboard_listener_extension_id();
  if (!current_id.empty() && extension()->id() != current_id)
    return RespondNow(Error("Existing keyboard listener registered."));

  manager->SetKeyboardListenerExtensionId(
      enabled ? extension()->id() : std::string(), details.GetProfile());

  ash::mojom::EventRewriterControllerPtr event_rewriter_controller_ptr;
  content::ServiceManagerConnection* connection =
      content::ServiceManagerConnection::GetForProcess();
  connection->GetConnector()->BindInterface(ash::mojom::kServiceName,
                                            &event_rewriter_controller_ptr);
  event_rewriter_controller_ptr->CaptureAllKeysForSpokenFeedback(enabled &&
                                                                 capture);
  return RespondNow(NoArguments());
#endif  // defined OS_CHROMEOS

  return RespondNow(Error(kErrorNotSupported));
}

ExtensionFunction::ResponseAction
AccessibilityPrivateDarkenScreenFunction::Run() {
#if defined(OS_CHROMEOS)
  bool darken = false;
  EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &darken));
  chromeos::AccessibilityManager::Get()->SetDarkenScreen(darken);
  return RespondNow(NoArguments());
#else
  return RespondNow(Error(kErrorNotSupported));
#endif
}

#if defined(OS_CHROMEOS)
ExtensionFunction::ResponseAction
AccessibilityPrivateSetSwitchAccessKeysFunction::Run() {
  std::unique_ptr<accessibility_private::SetSwitchAccessKeys::Params> params =
      accessibility_private::SetSwitchAccessKeys::Params::Create(*args_);
  EXTENSION_FUNCTION_VALIDATE(params);

  GetAccessibilityController()->SetSwitchAccessKeysToCapture(params->key_codes);

  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
AccessibilityPrivateSetNativeChromeVoxArcSupportForCurrentAppFunction::Run() {
  std::unique_ptr<
      accessibility_private::SetNativeChromeVoxArcSupportForCurrentApp::Params>
      params = accessibility_private::
          SetNativeChromeVoxArcSupportForCurrentApp::Params::Create(*args_);
  EXTENSION_FUNCTION_VALIDATE(params);

  ChromeExtensionFunctionDetails details(this);
  arc::ArcAccessibilityHelperBridge* bridge =
      arc::ArcAccessibilityHelperBridge::GetForBrowserContext(
          details.GetProfile());
  if (bridge) {
    bool enabled;
    EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
    bridge->SetNativeChromeVoxArcSupport(enabled);
  }
  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
AccessibilityPrivateSendSyntheticKeyEventFunction::Run() {
  std::unique_ptr<accessibility_private::SendSyntheticKeyEvent::Params> params =
      accessibility_private::SendSyntheticKeyEvent::Params::Create(*args_);
  EXTENSION_FUNCTION_VALIDATE(params);
  accessibility_private::SyntheticKeyboardEvent* key_data = &params->key_event;

  int modifiers = 0;
  if (key_data->modifiers.get()) {
    if (key_data->modifiers->ctrl && *key_data->modifiers->ctrl)
      modifiers |= ui::EF_CONTROL_DOWN;
    if (key_data->modifiers->alt && *key_data->modifiers->alt)
      modifiers |= ui::EF_ALT_DOWN;
    if (key_data->modifiers->search && *key_data->modifiers->search)
      modifiers |= ui::EF_COMMAND_DOWN;
    if (key_data->modifiers->shift && *key_data->modifiers->shift)
      modifiers |= ui::EF_SHIFT_DOWN;
  }

  std::unique_ptr<ui::KeyEvent> synthetic_key_event =
      std::make_unique<ui::KeyEvent>(
          key_data->type ==
                  accessibility_private::SYNTHETIC_KEYBOARD_EVENT_TYPE_KEYUP
              ? ui::ET_KEY_RELEASED
              : ui::ET_KEY_PRESSED,
          static_cast<ui::KeyboardCode>(key_data->key_code),
          static_cast<ui::DomCode>(0), modifiers);

  ws::mojom::EventInjectorPtr event_injector_ptr;
  content::ServiceManagerConnection* connection =
      content::ServiceManagerConnection::GetForProcess();
  connection->GetConnector()->BindInterface(ws::mojom::kServiceName,
                                            &event_injector_ptr);
  event_injector_ptr->InjectEventNoAckNoRewriters(
      display::Screen::GetScreen()->GetPrimaryDisplay().id(),
      std::move(synthetic_key_event));

  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
AccessibilityPrivateEnableChromeVoxMouseEventsFunction::Run() {
  bool enabled = false;
  EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &enabled));
  ash::mojom::EventRewriterControllerPtr event_rewriter_controller_ptr;
  content::ServiceManagerConnection* connection =
      content::ServiceManagerConnection::GetForProcess();
  connection->GetConnector()->BindInterface(ash::mojom::kServiceName,
                                            &event_rewriter_controller_ptr);
  event_rewriter_controller_ptr->SetSendMouseEventsToDelegate(enabled);
  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
AccessibilityPrivateSendSyntheticMouseEventFunction::Run() {
  std::unique_ptr<accessibility_private::SendSyntheticMouseEvent::Params>
      params = accessibility_private::SendSyntheticMouseEvent::Params::Create(
          *args_);
  EXTENSION_FUNCTION_VALIDATE(params);
  accessibility_private::SyntheticMouseEvent* mouse_data = &params->mouse_event;

  ui::EventType type;
  switch (mouse_data->type) {
    case accessibility_private::SYNTHETIC_MOUSE_EVENT_TYPE_PRESS:
      type = ui::ET_MOUSE_PRESSED;
      break;
    case accessibility_private::SYNTHETIC_MOUSE_EVENT_TYPE_RELEASE:
      type = ui::ET_MOUSE_RELEASED;
      break;
    case accessibility_private::SYNTHETIC_MOUSE_EVENT_TYPE_DRAG:
      type = ui::ET_MOUSE_DRAGGED;
      break;
    case accessibility_private::SYNTHETIC_MOUSE_EVENT_TYPE_MOVE:
      type = ui::ET_MOUSE_MOVED;
      break;
    case accessibility_private::SYNTHETIC_MOUSE_EVENT_TYPE_ENTER:
      type = ui::ET_MOUSE_ENTERED;
      break;
    case accessibility_private::SYNTHETIC_MOUSE_EVENT_TYPE_EXIT:
      type = ui::ET_MOUSE_EXITED;
      break;
    default:
      NOTREACHED();
  }

  int flags = ui::EF_LEFT_MOUSE_BUTTON;

  // Locations are assumed to be display relative (and in DIPs).
  // TODO(crbug/893752) Choose correct display
  display::Display display = display::Screen::GetScreen()->GetPrimaryDisplay();
  gfx::Point location(mouse_data->x, mouse_data->y);
  std::unique_ptr<ui::MouseEvent> synthetic_mouse_event =
      std::make_unique<ui::MouseEvent>(type, location, location,
                                       ui::EventTimeForNow(), flags,
                                       flags /* changed_button_flags */);

  ws::mojom::EventInjectorPtr event_injector_ptr;
  content::ServiceManagerConnection* connection =
      content::ServiceManagerConnection::GetForProcess();
  connection->GetConnector()->BindInterface(ws::mojom::kServiceName,
                                            &event_injector_ptr);
  event_injector_ptr->InjectEventNoAckNoRewriters(
      display.id(), std::move(synthetic_mouse_event));

  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
AccessibilityPrivateOnSelectToSpeakStateChangedFunction::Run() {
  std::unique_ptr<accessibility_private::OnSelectToSpeakStateChanged::Params>
      params =
          accessibility_private::OnSelectToSpeakStateChanged::Params::Create(
              *args_);
  EXTENSION_FUNCTION_VALIDATE(params);
  accessibility_private::SelectToSpeakState params_state = params->state;
  ash::mojom::SelectToSpeakState state;
  switch (params_state) {
    case accessibility_private::SelectToSpeakState::
        SELECT_TO_SPEAK_STATE_SELECTING:
      state = ash::mojom::SelectToSpeakState::kSelectToSpeakStateSelecting;
      break;
    case accessibility_private::SelectToSpeakState::
        SELECT_TO_SPEAK_STATE_SPEAKING:
      state = ash::mojom::SelectToSpeakState::kSelectToSpeakStateSpeaking;
      break;
    case accessibility_private::SelectToSpeakState::
        SELECT_TO_SPEAK_STATE_INACTIVE:
    case accessibility_private::SelectToSpeakState::SELECT_TO_SPEAK_STATE_NONE:
      state = ash::mojom::SelectToSpeakState::kSelectToSpeakStateInactive;
  }

  auto* accessibility_manager = chromeos::AccessibilityManager::Get();
  accessibility_manager->OnSelectToSpeakStateChanged(state);

  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
AccessibilityPrivateToggleDictationFunction::Run() {
  ash::mojom::DictationToggleSource source =
      ash::mojom::DictationToggleSource::kChromevox;
  if (extension()->id() == extension_misc::kSwitchAccessExtensionId)
    source = ash::mojom::DictationToggleSource::kSwitchAccess;
  else if (extension()->id() == extension_misc::kChromeVoxExtensionId)
    source = ash::mojom::DictationToggleSource::kChromevox;
  else
    NOTREACHED();

  GetAccessibilityController()->ToggleDictationFromSource(source);

  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
AccessibilityPrivateSetSwitchAccessMenuStateFunction::Run() {
  std::unique_ptr<accessibility_private::SetSwitchAccessMenuState::Params>
      params = accessibility_private::SetSwitchAccessMenuState::Params::Create(
          *args_);
  EXTENSION_FUNCTION_VALIDATE(params);

  chromeos::AccessibilityManager* manager =
      chromeos::AccessibilityManager::Get();

  if (!params->show) {
    manager->HideSwitchAccessMenu();
    return RespondNow(NoArguments());
  }

  accessibility_private::ScreenRect elem = std::move(params->element_bounds);
  gfx::Rect element_bounds(elem.left, elem.top, elem.width, elem.height);
  int item_count = params->item_count;

  // If we have an item count of 0, the panel is showing only the back button.
  if (item_count == 0) {
    manager->ShowSwitchAccessMenu(element_bounds, kBackButtonWidth,
                                  kBackButtonHeight,
                                  true /* back_button_only */);
    return RespondNow(NoArguments());
  }

  int padding = 40;
  int item_width = 88;
  int item_height = 60;
  // TODO(anastasi): This should be a preference that the user can change.
  int max_cols = 3;

  // The number of rows is the number of items divided by the max columns,
  // rounded down.
  int rows = 1 + (item_count - 1) / max_cols;
  int cols = rows == 1 ? item_count : max_cols;
  int width = padding + (item_width * cols);
  int height = padding + (item_height * rows);

  manager->ShowSwitchAccessMenu(element_bounds, width, height);
  return RespondNow(NoArguments());
}

ExtensionFunction::ResponseAction
AccessibilityPrivateForwardKeyEventsToSwitchAccessFunction::Run() {
  std::unique_ptr<accessibility_private::ForwardKeyEventsToSwitchAccess::Params>
      params =
          accessibility_private::ForwardKeyEventsToSwitchAccess::Params::Create(
              *args_);
  EXTENSION_FUNCTION_VALIDATE(params);

  GetAccessibilityController()->ForwardKeyEventsToSwitchAccess(
      params->should_forward);

  return RespondNow(NoArguments());
}

AccessibilityPrivateGetBatteryDescriptionFunction::
    AccessibilityPrivateGetBatteryDescriptionFunction() {}

AccessibilityPrivateGetBatteryDescriptionFunction::
    ~AccessibilityPrivateGetBatteryDescriptionFunction() {}

ExtensionFunction::ResponseAction
AccessibilityPrivateGetBatteryDescriptionFunction::Run() {
  // Get AccessibilityControllerPtr; needs to exist for lifetime of this
  // function and its callback.
  controller_ = GetAccessibilityController();

  // Get battery description from ash and return it via callback.
  controller_->GetBatteryDescription(
      base::BindOnce(&AccessibilityPrivateGetBatteryDescriptionFunction::
                         OnGotBatteryDescription,
                     this));

  return RespondLater();
}

void AccessibilityPrivateGetBatteryDescriptionFunction::OnGotBatteryDescription(
    const base::string16& battery_description) {
  // Send battery description to extension.
  Respond(OneArgument(std::make_unique<base::Value>(battery_description)));
  controller_.reset();
}

#endif  // defined (OS_CHROMEOS)
