// Copyright 2017 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/ui/ash/ime_controller_client.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/macros.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "chrome/browser/ui/ash/test_ime_controller.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ime/chromeos/fake_input_method_delegate.h"
#include "ui/base/ime/chromeos/input_method_descriptor.h"
#include "ui/base/ime/chromeos/input_method_util.h"
#include "ui/base/ime/chromeos/mock_ime_candidate_window_handler.h"
#include "ui/base/ime/chromeos/mock_input_method_manager.h"
#include "ui/base/ime/ime_bridge.h"

using chromeos::input_method::FakeInputMethodDelegate;
using chromeos::input_method::InputMethodDescriptor;
using chromeos::input_method::InputMethodManager;
using chromeos::input_method::InputMethodUtil;
using chromeos::input_method::MockInputMethodManager;
using ui::ime::InputMethodMenuItem;
using ui::ime::InputMethodMenuManager;

namespace {

// Used to look up IME names.
base::string16 GetLocalizedString(int resource_id) {
  return base::ASCIIToUTF16("localized string");
}

// InputMethodManager with available IMEs.
class TestInputMethodManager : public MockInputMethodManager {
 public:
  class TestState : public MockInputMethodManager::State {
   public:
    TestState() {
      // Set up two input methods.
      std::vector<std::string> layouts({"us"});
      std::vector<std::string> languages({"en-US"});
      InputMethodDescriptor ime1("id1", "name1", "indicator1", layouts,
                                 languages, true /* is_login_keyboard */,
                                 GURL(), GURL());
      InputMethodDescriptor ime2("id2", "name2", "indicator2", layouts,
                                 languages, false /* is_login_keyboard */,
                                 GURL(), GURL());
      current_ime_id_ = ime1.id();
      input_methods_ = {ime1, ime2};
    }

    // MockInputMethodManager::State:
    void ChangeInputMethod(const std::string& input_method_id,
                           bool show_message) override {
      ++change_input_method_count_;
      current_ime_id_ = input_method_id;
      last_show_message_ = show_message;
    }
    std::unique_ptr<std::vector<InputMethodDescriptor>> GetActiveInputMethods()
        const override {
      return std::make_unique<std::vector<InputMethodDescriptor>>(
          input_methods_);
    }
    const InputMethodDescriptor* GetInputMethodFromId(
        const std::string& input_method_id) const override {
      for (const InputMethodDescriptor& descriptor : input_methods_) {
        if (input_method_id == descriptor.id())
          return &descriptor;
      }
      return nullptr;
    }
    InputMethodDescriptor GetCurrentInputMethod() const override {
      for (const InputMethodDescriptor& descriptor : input_methods_) {
        if (current_ime_id_ == descriptor.id())
          return descriptor;
      }
      return InputMethodUtil::GetFallbackInputMethodDescriptor();
    }
    void SwitchToNextInputMethod() override { ++next_input_method_count_; }
    void SwitchToLastUsedInputMethod() override {
      ++previous_input_method_count_;
    }

    std::string current_ime_id_;
    std::vector<InputMethodDescriptor> input_methods_;
    int next_input_method_count_ = 0;
    int previous_input_method_count_ = 0;
    int change_input_method_count_ = 0;
    bool last_show_message_ = false;

   protected:
    friend base::RefCounted<InputMethodManager::State>;
    ~TestState() override {}

    DISALLOW_COPY_AND_ASSIGN(TestState);
  };

  TestInputMethodManager() : state_(new TestState), util_(&delegate_) {}
  ~TestInputMethodManager() override = default;

  // MockInputMethodManager:
  void AddObserver(InputMethodManager::Observer* observer) override {
    ++add_observer_count_;
  }
  void AddImeMenuObserver(ImeMenuObserver* observer) override {
    ++add_menu_observer_count_;
  }
  void RemoveObserver(InputMethodManager::Observer* observer) override {
    ++remove_observer_count_;
  }
  void RemoveImeMenuObserver(ImeMenuObserver* observer) override {
    ++remove_menu_observer_count_;
  }
  void ActivateInputMethodMenuItem(const std::string& key) override {
    last_activate_menu_item_key_ = key;
  }
  void OverrideKeyboardKeyset(
      chromeos::input_method::mojom::ImeKeyset keyset) override {
    keyboard_keyset_ = keyset;
  }

  InputMethodUtil* GetInputMethodUtil() override { return &util_; }
  scoped_refptr<InputMethodManager::State> GetActiveIMEState() override {
    return state_;
  }

  scoped_refptr<TestState> state_;
  int add_observer_count_ = 0;
  int remove_observer_count_ = 0;
  int add_menu_observer_count_ = 0;
  int remove_menu_observer_count_ = 0;
  std::string last_activate_menu_item_key_;
  chromeos::input_method::mojom::ImeKeyset keyboard_keyset_;
  FakeInputMethodDelegate delegate_;
  InputMethodUtil util_;

 private:
  DISALLOW_COPY_AND_ASSIGN(TestInputMethodManager);
};

class ImeControllerClientTest : public testing::Test {
 public:
  ImeControllerClientTest() {
    input_method_manager_.delegate_.set_get_localized_string_callback(
        base::Bind(&GetLocalizedString));
  }
  ~ImeControllerClientTest() override = default;

 protected:
  TestInputMethodManager input_method_manager_;

  // Mock of mojo interface in ash.
  TestImeController ime_controller_;

 private:
  base::test::ScopedTaskEnvironment scoped_task_environment_;

  DISALLOW_COPY_AND_ASSIGN(ImeControllerClientTest);
};

TEST_F(ImeControllerClientTest, Construction) {
  std::unique_ptr<ImeControllerClient> client =
      std::make_unique<ImeControllerClient>(&input_method_manager_);
  client->InitForTesting(ime_controller_.CreateInterfacePtr());
  EXPECT_EQ(1, input_method_manager_.add_observer_count_);
  EXPECT_EQ(1, input_method_manager_.add_menu_observer_count_);

  client.reset();
  EXPECT_EQ(1, input_method_manager_.remove_observer_count_);
  EXPECT_EQ(1, input_method_manager_.remove_menu_observer_count_);
}

TEST_F(ImeControllerClientTest, SetImesManagedByPolicy) {
  ImeControllerClient client(&input_method_manager_);
  client.InitForTesting(ime_controller_.CreateInterfacePtr());

  client.SetImesManagedByPolicy(true);
  client.FlushMojoForTesting();
  EXPECT_TRUE(ime_controller_.managed_by_policy_);
}

TEST_F(ImeControllerClientTest, CapsLock) {
  ImeControllerClient client(&input_method_manager_);
  client.InitForTesting(ime_controller_.CreateInterfacePtr());

  client.OnCapsLockChanged(true);
  client.FlushMojoForTesting();
  EXPECT_TRUE(ime_controller_.is_caps_lock_enabled_);

  client.OnCapsLockChanged(false);
  client.FlushMojoForTesting();
  EXPECT_FALSE(ime_controller_.is_caps_lock_enabled_);
}

TEST_F(ImeControllerClientTest, LayoutName) {
  ImeControllerClient client(&input_method_manager_);
  client.InitForTesting(ime_controller_.CreateInterfacePtr());

  client.OnLayoutChanging("us(dvorak)");
  client.FlushMojoForTesting();
  EXPECT_EQ("us(dvorak)", ime_controller_.keyboard_layout_name_);

  client.OnLayoutChanging("us");
  client.FlushMojoForTesting();
  EXPECT_EQ("us", ime_controller_.keyboard_layout_name_);
}

TEST_F(ImeControllerClientTest, ExtraInputEnabledStateChange) {
  ImeControllerClient client(&input_method_manager_);
  client.InitForTesting(ime_controller_.CreateInterfacePtr());

  client.OnExtraInputEnabledStateChange(true, true, false, false);
  client.FlushMojoForTesting();
  EXPECT_TRUE(ime_controller_.is_extra_input_options_enabled_);
  EXPECT_TRUE(ime_controller_.is_emoji_enabled_);
  EXPECT_FALSE(ime_controller_.is_handwriting_enabled_);
  EXPECT_FALSE(ime_controller_.is_voice_enabled_);

  client.OnExtraInputEnabledStateChange(true, false, true, true);
  client.FlushMojoForTesting();
  EXPECT_TRUE(ime_controller_.is_extra_input_options_enabled_);
  EXPECT_FALSE(ime_controller_.is_emoji_enabled_);
  EXPECT_TRUE(ime_controller_.is_handwriting_enabled_);
  EXPECT_TRUE(ime_controller_.is_voice_enabled_);

  client.OnExtraInputEnabledStateChange(false, false, false, false);
  client.FlushMojoForTesting();
  EXPECT_FALSE(ime_controller_.is_extra_input_options_enabled_);
  EXPECT_FALSE(ime_controller_.is_emoji_enabled_);
  EXPECT_FALSE(ime_controller_.is_handwriting_enabled_);
  EXPECT_FALSE(ime_controller_.is_voice_enabled_);
}

TEST_F(ImeControllerClientTest, ShowImeMenuOnShelf) {
  ImeControllerClient client(&input_method_manager_);
  client.InitForTesting(ime_controller_.CreateInterfacePtr());

  client.ImeMenuActivationChanged(true);
  client.FlushMojoForTesting();
  EXPECT_TRUE(ime_controller_.show_ime_menu_on_shelf_);
}

TEST_F(ImeControllerClientTest, InputMethodChanged) {
  ui::IMEBridge::Initialize();
  std::unique_ptr<chromeos::MockIMECandidateWindowHandler>
      mock_candidate_window =
          std::make_unique<chromeos::MockIMECandidateWindowHandler>();
  ui::IMEBridge::Get()->SetCandidateWindowHandler(mock_candidate_window.get());

  ImeControllerClient client(&input_method_manager_);
  client.InitForTesting(ime_controller_.CreateInterfacePtr());

  // Simulate a switch to IME 2.
  input_method_manager_.state_->current_ime_id_ = "id2";
  client.InputMethodChanged(&input_method_manager_, nullptr /* profile */,
                            false /* show_message */);
  client.FlushMojoForTesting();

  // IME controller received the change and the list of available IMEs.
  EXPECT_EQ("id2", ime_controller_.current_ime_id_);
  ASSERT_EQ(2u, ime_controller_.available_imes_.size());
  EXPECT_EQ("id1", ime_controller_.available_imes_[0]->id);
  EXPECT_EQ(base::ASCIIToUTF16("name1"),
            ime_controller_.available_imes_[0]->name);
  EXPECT_EQ("id2", ime_controller_.available_imes_[1]->id);
  EXPECT_EQ(base::ASCIIToUTF16("name2"),
            ime_controller_.available_imes_[1]->name);
  EXPECT_FALSE(ime_controller_.show_mode_indicator_);

  // Simulate a switch and show message.
  input_method_manager_.state_->current_ime_id_ = "id1";
  client.InputMethodChanged(&input_method_manager_, nullptr /* profile */,
                            true /* show_message */);
  client.FlushMojoForTesting();

  // Mode indicator should be shown.
  EXPECT_TRUE(ime_controller_.show_mode_indicator_);
}

TEST_F(ImeControllerClientTest, NoActiveState) {
  ImeControllerClient client(&input_method_manager_);
  client.InitForTesting(ime_controller_.CreateInterfacePtr());

  input_method_manager_.state_ = nullptr;
  client.InputMethodChanged(&input_method_manager_, nullptr /* profile */,
                            false /* show_message */);
  client.FlushMojoForTesting();
  EXPECT_TRUE(ime_controller_.current_ime_id_.empty());
  EXPECT_TRUE(ime_controller_.available_imes_.empty());
  EXPECT_TRUE(ime_controller_.menu_items_.empty());
}

TEST_F(ImeControllerClientTest, MenuItemChanged) {
  ImeControllerClient client(&input_method_manager_);
  client.InitForTesting(ime_controller_.CreateInterfacePtr());
  const bool is_selection_item = true;
  InputMethodMenuItem item1("key1", "label1", is_selection_item,
                            true /* checked */);
  InputMethodMenuItem item2("key2", "label2", is_selection_item,
                            false /* checked */);

  // Setting the list triggers the InputMethodMenuItemChanged event.
  InputMethodMenuManager::GetInstance()->SetCurrentInputMethodMenuItemList(
      {item1, item2});
  client.FlushMojoForTesting();

  // IME controller received the menu items.
  ASSERT_EQ(2u, ime_controller_.menu_items_.size());
  EXPECT_EQ("key1", ime_controller_.menu_items_[0]->key);
  EXPECT_TRUE(ime_controller_.menu_items_[0]->checked);
  EXPECT_EQ("key2", ime_controller_.menu_items_[1]->key);
  EXPECT_FALSE(ime_controller_.menu_items_[1]->checked);
}

TEST_F(ImeControllerClientTest, SwitchToNextIme) {
  ImeControllerClient client(&input_method_manager_);
  client.SwitchToNextIme();
  EXPECT_EQ(1, input_method_manager_.state_->next_input_method_count_);
}

TEST_F(ImeControllerClientTest, SwitchToPreviousIme) {
  ImeControllerClient client(&input_method_manager_);
  client.SwitchToLastUsedIme();
  EXPECT_EQ(1, input_method_manager_.state_->previous_input_method_count_);
}

TEST_F(ImeControllerClientTest, SwitchImeById) {
  ImeControllerClient client(&input_method_manager_);
  client.SwitchImeById("id2", true /* show_message */);
  EXPECT_EQ(1, input_method_manager_.state_->change_input_method_count_);
  EXPECT_EQ("id2", input_method_manager_.state_->current_ime_id_);
  EXPECT_TRUE(input_method_manager_.state_->last_show_message_);

  client.SwitchImeById("id1", false /* show_message */);
  EXPECT_EQ(2, input_method_manager_.state_->change_input_method_count_);
  EXPECT_EQ("id1", input_method_manager_.state_->current_ime_id_);
  EXPECT_FALSE(input_method_manager_.state_->last_show_message_);
}

TEST_F(ImeControllerClientTest, ActivateImeMenuItem) {
  ImeControllerClient client(&input_method_manager_);
  client.ActivateImeMenuItem("key1");
  EXPECT_EQ("key1", input_method_manager_.last_activate_menu_item_key_);
}

TEST_F(ImeControllerClientTest, OverrideKeyboardKeyset) {
  ImeControllerClient client(&input_method_manager_);
  bool callback_called = false;
  client.OverrideKeyboardKeyset(
      chromeos::input_method::mojom::ImeKeyset::kEmoji,
      base::BindLambdaForTesting(
          [&callback_called]() { callback_called = true; }));
  EXPECT_EQ(chromeos::input_method::mojom::ImeKeyset::kEmoji,
            input_method_manager_.keyboard_keyset_);
  EXPECT_TRUE(callback_called);
}

}  // namespace
