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

#include "ash/keyboard/ash_keyboard_ui.h"
#include "ash/keyboard/virtual_keyboard_controller.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/root_window_controller.h"
#include "ash/session/session_controller.h"
#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ui/base/ui_base_features.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/keyboard/keyboard_controller.h"
#include "ui/keyboard/keyboard_ui_factory.h"
#include "ui/wm/core/coordinate_conversion.h"

using keyboard::mojom::KeyboardConfig;
using keyboard::mojom::KeyboardConfigPtr;
using keyboard::mojom::KeyboardEnableFlag;

namespace ash {

AshKeyboardController::AshKeyboardController(
    SessionController* session_controller)
    : session_controller_(session_controller),
      keyboard_controller_(std::make_unique<keyboard::KeyboardController>()) {
  if (session_controller_)  // May be null in tests.
    session_controller_->AddObserver(this);
  keyboard_controller_->AddObserver(this);
}

AshKeyboardController::~AshKeyboardController() {
  keyboard_controller_->RemoveObserver(this);
  if (session_controller_)  // May be null in tests.
    session_controller_->RemoveObserver(this);
}

void AshKeyboardController::BindRequest(
    mojom::KeyboardControllerRequest request) {
  bindings_.AddBinding(this, std::move(request));
}

void AshKeyboardController::EnableKeyboard() {
  if (!keyboard_controller_->IsKeyboardEnableRequested())
    return;

  // KeyboardController::EnableKeyboard will reload the keyboard if it's already
  // enabled. TODO(https://crbug.com/731537): Add a separate function for
  // reloading the keyboard.
  keyboard_controller_->EnableKeyboard(
      keyboard_ui_factory_ ? keyboard_ui_factory_->CreateKeyboardUI()
                           : std::make_unique<AshKeyboardUI>(this),
      virtual_keyboard_controller_.get());
  ActivateKeyboard();
}

void AshKeyboardController::DisableKeyboard() {
  keyboard_controller_->DisableKeyboard();
}

void AshKeyboardController::CreateVirtualKeyboard(
    std::unique_ptr<keyboard::KeyboardUIFactory> keyboard_ui_factory) {
  DCHECK(keyboard_ui_factory || features::IsUsingWindowService())
      << "keyboard_ui_factory can be null only when window service is used.";
  keyboard_ui_factory_ = std::move(keyboard_ui_factory);
  virtual_keyboard_controller_ = std::make_unique<VirtualKeyboardController>();
}

void AshKeyboardController::DestroyVirtualKeyboard() {
  virtual_keyboard_controller_.reset();
}

void AshKeyboardController::SendOnKeyboardVisibleBoundsChanged(
    const gfx::Rect& bounds) {
  DVLOG(1) << "OnKeyboardVisibleBoundsChanged: " << bounds.ToString();
  // Pass the bounds in screen coordinates over mojo.
  gfx::Rect screen_bounds = BoundsToScreen(bounds);
  observers_.ForAllPtrs(
      [&screen_bounds](mojom::KeyboardControllerObserver* observer) {
        observer->OnKeyboardVisibleBoundsChanged(screen_bounds);
      });
}

void AshKeyboardController::SendOnLoadKeyboardContentsRequested() {
  observers_.ForAllPtrs([](mojom::KeyboardControllerObserver* observer) {
    observer->OnLoadKeyboardContentsRequested();
  });
}

void AshKeyboardController::SendOnKeyboardUIDestroyed() {
  observers_.ForAllPtrs([](mojom::KeyboardControllerObserver* observer) {
    observer->OnKeyboardUIDestroyed();
  });
}

// mojom::KeyboardController

void AshKeyboardController::KeyboardContentsLoaded(
    const base::UnguessableToken& token,
    const gfx::Size& size) {
  keyboard_controller()->KeyboardContentsLoaded(token, size);
}

void AshKeyboardController::GetKeyboardConfig(
    GetKeyboardConfigCallback callback) {
  std::move(callback).Run(
      KeyboardConfig::New(keyboard_controller_->keyboard_config()));
}

void AshKeyboardController::SetKeyboardConfig(
    KeyboardConfigPtr keyboard_config) {
  keyboard_controller_->UpdateKeyboardConfig(*keyboard_config);
}

void AshKeyboardController::IsKeyboardEnabled(
    IsKeyboardEnabledCallback callback) {
  std::move(callback).Run(keyboard_controller_->IsEnabled());
}

void AshKeyboardController::SetEnableFlag(KeyboardEnableFlag flag) {
  bool was_enabled = keyboard_controller_->IsEnabled();
  keyboard_controller_->SetEnableFlag(flag);
  UpdateEnableFlag(was_enabled);
}

void AshKeyboardController::ClearEnableFlag(KeyboardEnableFlag flag) {
  bool was_enabled = keyboard_controller_->IsEnabled();
  keyboard_controller_->ClearEnableFlag(flag);
  UpdateEnableFlag(was_enabled);
}

void AshKeyboardController::GetEnableFlags(GetEnableFlagsCallback callback) {
  const std::set<keyboard::mojom::KeyboardEnableFlag>& keyboard_enable_flags =
      keyboard_controller_->keyboard_enable_flags();
  std::vector<keyboard::mojom::KeyboardEnableFlag> flags(
      keyboard_enable_flags.begin(), keyboard_enable_flags.end());
  std::move(callback).Run(std::move(flags));
}

void AshKeyboardController::ReloadKeyboardIfNeeded() {
  keyboard_controller_->Reload();
}

void AshKeyboardController::RebuildKeyboardIfEnabled() {
  // Test IsKeyboardEnableRequested in case of an unlikely edge case where this
  // is called while after the enable state changed to disabled (in which case
  // we do not want to override the requested state).
  if (keyboard_controller_->IsKeyboardEnableRequested())
    EnableKeyboard();
}

void AshKeyboardController::IsKeyboardVisible(
    IsKeyboardVisibleCallback callback) {
  std::move(callback).Run(keyboard_controller_->IsKeyboardVisible());
}

void AshKeyboardController::ShowKeyboard() {
  if (keyboard_controller_->IsEnabled())
    keyboard_controller_->ShowKeyboard(false /* lock */);
}

void AshKeyboardController::HideKeyboard(mojom::HideReason reason) {
  if (!keyboard_controller_->IsEnabled())
    return;
  switch (reason) {
    case mojom::HideReason::kUser:
      keyboard_controller_->HideKeyboardByUser();
      break;
    case mojom::HideReason::kSystem:
      keyboard_controller_->HideKeyboardExplicitlyBySystem();
      break;
  }
}

void AshKeyboardController::SetContainerType(
    keyboard::mojom::ContainerType container_type,
    const base::Optional<gfx::Rect>& target_bounds,
    SetContainerTypeCallback callback) {
  keyboard_controller_->SetContainerType(container_type, target_bounds,
                                         std::move(callback));
}

void AshKeyboardController::SetKeyboardLocked(bool locked) {
  keyboard_controller_->set_keyboard_locked(locked);
}

void AshKeyboardController::SetOccludedBounds(
    const std::vector<gfx::Rect>& bounds) {
  // TODO(https://crbug.com/826617): Support occluded bounds with multiple
  // rectangles.
  keyboard_controller_->SetOccludedBounds(bounds.empty() ? gfx::Rect()
                                                         : bounds[0]);
}

void AshKeyboardController::SetHitTestBounds(
    const std::vector<gfx::Rect>& bounds) {
  keyboard_controller_->SetHitTestBounds(bounds);
}

void AshKeyboardController::SetDraggableArea(const gfx::Rect& bounds) {
  keyboard_controller_->SetDraggableArea(bounds);
}

void AshKeyboardController::AddObserver(
    mojom::KeyboardControllerObserverAssociatedPtrInfo observer) {
  mojom::KeyboardControllerObserverAssociatedPtr observer_ptr;
  observer_ptr.Bind(std::move(observer));
  observers_.AddPtr(std::move(observer_ptr));
}

// SessionObserver
void AshKeyboardController::OnSessionStateChanged(
    session_manager::SessionState state) {
  if (!keyboard_controller_->IsKeyboardEnableRequested())
    return;

  switch (state) {
    case session_manager::SessionState::OOBE:
    case session_manager::SessionState::LOGIN_PRIMARY:
      ActivateKeyboard();
      break;
    case session_manager::SessionState::LOGGED_IN_NOT_ACTIVE:
    case session_manager::SessionState::ACTIVE:
      // Reload the keyboard on user profile change to refresh keyboard
      // extensions with the new profile and ensure the extensions call the
      // proper IME. |LOGGED_IN_NOT_ACTIVE| is needed so that the virtual
      // keyboard works on supervised user creation, http://crbug.com/712873.
      // |ACTIVE| is also needed for guest user workflow.
      EnableKeyboard();
      break;
    default:
      break;
  }
}

// private methods

void AshKeyboardController::ActivateKeyboard() {
  ActivateKeyboardForRoot(Shell::Get()->GetPrimaryRootWindowController());
}

void AshKeyboardController::ActivateKeyboardForRoot(
    RootWindowController* controller) {
  DCHECK(controller);
  // If the keyboard is already activated, do nothing.
  if (!keyboard_controller_->IsEnabled() ||
      keyboard_controller_->GetRootWindow()) {
    if (keyboard_controller_->GetRootWindow() != controller->GetRootWindow()) {
      LOG(ERROR)
          << "Tried to activate an already activated virtual keyboard on a "
             "different root window";
    }
    return;
  }

  aura::Window* container =
      controller->GetContainer(kShellWindowId_VirtualKeyboardContainer);
  DCHECK(container);
  keyboard_controller_->ActivateKeyboardInContainer(container);
  keyboard_controller_->LoadKeyboardWindowInBackground();
}

void AshKeyboardController::DeactivateKeyboard() {
  if (!keyboard_controller_->IsEnabled() ||
      !keyboard_controller_->GetRootWindow()) {
    return;
  }
  keyboard_controller_->DeactivateKeyboard();
}

void AshKeyboardController::OnRootWindowClosing(aura::Window* root_window) {
  if (keyboard_controller_->GetRootWindow() == root_window)
    DeactivateKeyboard();
}

void AshKeyboardController::UpdateEnableFlag(bool was_enabled) {
  bool is_enabled = keyboard_controller_->IsKeyboardEnableRequested();
  if (is_enabled && !was_enabled) {
    EnableKeyboard();
  } else if (!is_enabled && was_enabled) {
    DisableKeyboard();
  }
}

void AshKeyboardController::OnKeyboardConfigChanged() {
  KeyboardConfigPtr config =
      KeyboardConfig::New(keyboard_controller_->keyboard_config());
  observers_.ForAllPtrs([&config](mojom::KeyboardControllerObserver* observer) {
    observer->OnKeyboardConfigChanged(config.Clone());
  });
}

void AshKeyboardController::OnKeyboardVisibilityStateChanged(bool is_visible) {
  observers_.ForAllPtrs(
      [is_visible](mojom::KeyboardControllerObserver* observer) {
        observer->OnKeyboardVisibilityChanged(is_visible);
      });
}

void AshKeyboardController::OnKeyboardVisibleBoundsChanged(
    const gfx::Rect& bounds) {
  SendOnKeyboardVisibleBoundsChanged(bounds);
}

void AshKeyboardController::OnKeyboardWorkspaceOccludedBoundsChanged(
    const gfx::Rect& bounds) {
  DVLOG(1) << "OnKeyboardOccludedBoundsChanged: " << bounds.ToString();
  // Pass the bounds in screen coordinates over mojo.
  gfx::Rect screen_bounds = BoundsToScreen(bounds);
  observers_.ForAllPtrs(
      [&screen_bounds](mojom::KeyboardControllerObserver* observer) {
        observer->OnKeyboardOccludedBoundsChanged(screen_bounds);
      });
}

void AshKeyboardController::OnKeyboardEnableFlagsChanged(
    std::set<keyboard::mojom::KeyboardEnableFlag>& keyboard_enable_flags) {
  std::vector<keyboard::mojom::KeyboardEnableFlag> flags(
      keyboard_enable_flags.begin(), keyboard_enable_flags.end());
  observers_.ForAllPtrs([&flags](mojom::KeyboardControllerObserver* observer) {
    observer->OnKeyboardEnableFlagsChanged(flags);
  });
}

void AshKeyboardController::OnKeyboardEnabledChanged(bool is_enabled) {
  observers_.ForAllPtrs(
      [is_enabled](mojom::KeyboardControllerObserver* observer) {
        observer->OnKeyboardEnabledChanged(is_enabled);
      });
}

gfx::Rect AshKeyboardController::BoundsToScreen(const gfx::Rect& bounds) {
  DCHECK(keyboard_controller_->GetKeyboardWindow());
  gfx::Rect screen_bounds(bounds);
  ::wm::ConvertRectToScreen(keyboard_controller_->GetKeyboardWindow(),
                            &screen_bounds);
  return screen_bounds;
}

}  // namespace ash
