// Copyright 2014 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 "remoting/host/input_injector_chromeos.h"

#include <set>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "remoting/host/chromeos/point_transformer.h"
#include "remoting/host/clipboard.h"
#include "remoting/proto/internal.pb.h"
#include "ui/base/ime/chromeos/ime_keyboard.h"
#include "ui/base/ime/chromeos/input_method_manager.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/events/system_input_injector.h"

namespace remoting {

using protocol::ClipboardEvent;
using protocol::KeyEvent;
using protocol::MouseEvent;
using protocol::TextEvent;
using protocol::TouchEvent;

namespace {

ui::EventFlags MouseButtonToUIFlags(MouseEvent::MouseButton button) {
  switch (button) {
    case MouseEvent::BUTTON_LEFT:
      return ui::EF_LEFT_MOUSE_BUTTON;
    case MouseEvent::BUTTON_RIGHT:
      return ui::EF_RIGHT_MOUSE_BUTTON;
    case MouseEvent::BUTTON_MIDDLE:
      return ui::EF_MIDDLE_MOUSE_BUTTON;
    default:
      NOTREACHED();
      return ui::EF_NONE;
  }
}

// Check if the given key could be mapped to caps lock
bool IsLockKey(ui::DomCode dom_code) {
  switch (dom_code) {
    // Ignores all the keys that could possibly be mapped to Caps Lock in event
    // rewriter. Please refer to ui::EventRewriterChromeOS::RewriteModifierKeys.
    case ui::DomCode::F16:
    case ui::DomCode::CAPS_LOCK:
    case ui::DomCode::META_LEFT:
    case ui::DomCode::META_RIGHT:
    case ui::DomCode::CONTROL_LEFT:
    case ui::DomCode::CONTROL_RIGHT:
    case ui::DomCode::ALT_LEFT:
    case ui::DomCode::ALT_RIGHT:
    case ui::DomCode::ESCAPE:
    case ui::DomCode::BACKSPACE:
      return true;
    default:
      return false;
  }
}

// If caps_lock is specified, sets local keyboard state to match.
void SetCapsLockState(bool caps_lock) {
  chromeos::input_method::InputMethodManager* ime =
      chromeos::input_method::InputMethodManager::Get();
  ime->GetImeKeyboard()->SetCapsLockEnabled(caps_lock);
}

}  // namespace

// This class is run exclusively on the UI thread of the browser process.
class InputInjectorChromeos::Core {
 public:
  Core(ui::SystemInputInjectorFactory* system_input_injector_factory);

  // Mirrors the public InputInjectorChromeos interface.
  void InjectClipboardEvent(const ClipboardEvent& event);
  void InjectKeyEvent(const KeyEvent& event);
  void InjectTextEvent(const TextEvent& event);
  void InjectMouseEvent(const MouseEvent& event);
  void Start(std::unique_ptr<protocol::ClipboardStub> client_clipboard);

 private:
  void SetLockStates(uint32_t states);

  std::unique_ptr<ui::SystemInputInjector> delegate_;
  std::unique_ptr<Clipboard> clipboard_;

  // Used to rotate the input coordinates appropriately based on the current
  // display rotation settings.
  std::unique_ptr<PointTransformer> point_transformer_;

  // Creates |delegate_|. We store this since Core is created on one thread,
  // but then Start() is run on a different one.
  ui::SystemInputInjectorFactory* system_input_injector_factory_;

  DISALLOW_COPY_AND_ASSIGN(Core);
};

InputInjectorChromeos::Core::Core(
    ui::SystemInputInjectorFactory* system_input_injector_factory)
    : system_input_injector_factory_(system_input_injector_factory) {}

void InputInjectorChromeos::Core::InjectClipboardEvent(
    const ClipboardEvent& event) {
  clipboard_->InjectClipboardEvent(event);
}

void InputInjectorChromeos::Core::InjectKeyEvent(const KeyEvent& event) {
  DCHECK(event.has_pressed());
  DCHECK(event.has_usb_keycode());

  ui::DomCode dom_code =
      ui::KeycodeConverter::UsbKeycodeToDomCode(event.usb_keycode());

  if (event.pressed() && !IsLockKey(dom_code)) {
    if (event.has_caps_lock_state()) {
      SetCapsLockState(event.caps_lock_state());
    } else if (event.has_lock_states()) {
      SetCapsLockState((event.lock_states() &
                        protocol::KeyEvent::LOCK_STATES_CAPSLOCK) != 0);
    }
  }

  // Ignore events which can't be mapped.
  if (dom_code != ui::DomCode::NONE) {
    delegate_->InjectKeyEvent(dom_code, event.pressed(),
                              true /* suppress_auto_repeat */);
  }
}

void InputInjectorChromeos::Core::InjectTextEvent(const TextEvent& event) {
  // Chrome OS only supports It2Me, which is not supported on mobile clients, so
  // we don't need to implement text events.
  NOTIMPLEMENTED();
}

void InputInjectorChromeos::Core::InjectMouseEvent(const MouseEvent& event) {
  if (event.has_button() && event.has_button_down()) {
    delegate_->InjectMouseButton(MouseButtonToUIFlags(event.button()),
                                 event.button_down());
  } else if (event.has_wheel_delta_y() || event.has_wheel_delta_x()) {
    delegate_->InjectMouseWheel(event.wheel_delta_x(), event.wheel_delta_y());
  } else {
    DCHECK(event.has_x() && event.has_y());
    delegate_->MoveCursorTo(point_transformer_->ToScreenCoordinates(
        gfx::PointF(event.x(), event.y())));
  }
}

void InputInjectorChromeos::Core::Start(
    std::unique_ptr<protocol::ClipboardStub> client_clipboard) {
  // OK, so we now need to plumb from ChromotingHostContext to here.
  delegate_ = system_input_injector_factory_->CreateSystemInputInjector();
  DCHECK(delegate_);

  // Implemented by remoting::ClipboardAura.
  clipboard_ = Clipboard::Create();
  clipboard_->Start(std::move(client_clipboard));
  point_transformer_.reset(new PointTransformer());
}

InputInjectorChromeos::InputInjectorChromeos(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
    ui::SystemInputInjectorFactory* system_input_injector_factory)
    : input_task_runner_(task_runner) {
  core_.reset(new Core(system_input_injector_factory));
}

InputInjectorChromeos::~InputInjectorChromeos() {
  input_task_runner_->DeleteSoon(FROM_HERE, core_.release());
}

void InputInjectorChromeos::InjectClipboardEvent(const ClipboardEvent& event) {
  input_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&Core::InjectClipboardEvent,
                                base::Unretained(core_.get()), event));
}

void InputInjectorChromeos::InjectKeyEvent(const KeyEvent& event) {
  input_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&Core::InjectKeyEvent,
                                base::Unretained(core_.get()), event));
}

void InputInjectorChromeos::InjectTextEvent(const TextEvent& event) {
  input_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&Core::InjectTextEvent,
                                base::Unretained(core_.get()), event));
}

void InputInjectorChromeos::InjectMouseEvent(const MouseEvent& event) {
  input_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&Core::InjectMouseEvent,
                                base::Unretained(core_.get()), event));
}

void InputInjectorChromeos::InjectTouchEvent(const TouchEvent& event) {
  NOTIMPLEMENTED() << "Raw touch event injection not implemented for ChromeOS.";
}

void InputInjectorChromeos::Start(
    std::unique_ptr<protocol::ClipboardStub> client_clipboard) {
  input_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&Core::Start, base::Unretained(core_.get()),
                                std::move(client_clipboard)));
}

// static
std::unique_ptr<InputInjector> InputInjector::Create(
    scoped_refptr<base::SingleThreadTaskRunner> input_task_runner,
    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
    ui::SystemInputInjectorFactory* system_input_injector_factory) {
  // The Ozone input injector must be called on the UI task runner of the
  // browser process.
  return base::WrapUnique(
      new InputInjectorChromeos(ui_task_runner, system_input_injector_factory));
}

// static
bool InputInjector::SupportsTouchEvents() {
  return false;
}

}  // namespace remoting
