// 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::Bind(&Core::InjectClipboardEvent,
                            base::Unretained(core_.get()), event));
}

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

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

void InputInjectorChromeos::InjectMouseEvent(const MouseEvent& event) {
  input_task_runner_->PostTask(
      FROM_HERE, base::Bind(&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::Bind(&Core::Start, base::Unretained(core_.get()),
                            base::Passed(&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
