// 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/chromeos/preferences.h"

#include <memory>
#include <utility>

#include "ash/constants/ash_features.h"
#include "base/json/json_string_value_serializer.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "chrome/browser/ash/login/session/user_session_manager.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/chromeos/input_method/input_method_configuration.h"
#include "chrome/browser/chromeos/input_method/mock_input_method_manager_impl.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/language/core/browser/pref_names.h"
#include "components/prefs/pref_member.h"
#include "components/sync/base/client_tag_hash.h"
#include "components/sync/base/model_type.h"
#include "components/sync/model/sync_change.h"
#include "components/sync/model/sync_data.h"
#include "components/sync/model/sync_error_factory.h"
#include "components/sync/model/syncable_service.h"
#include "components/sync/protocol/preference_specifics.pb.h"
#include "components/sync/protocol/sync.pb.h"
#include "components/sync/test/model/fake_sync_change_processor.h"
#include "components/sync/test/model/sync_error_factory_mock.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "components/user_manager/scoped_user_manager.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/ime/chromeos/extension_ime_util.h"
#include "ui/base/ime/chromeos/mock_component_extension_ime_manager_delegate.h"
#include "url/gurl.h"

namespace chromeos {
namespace {

const char kIdentityIMEID[] =
    "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpIdentityIME";
const char kToUpperIMEID[] =
    "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpToUpperIME";
const char kAPIArgumentIMEID[] =
    "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpAPIArgumentIME";
const char kUnknownIMEID[] =
    "_ext_ime_iafoklpfplgfnoimmaejoeondnjnlcfpUnknownIME";

syncer::SyncData
CreatePrefSyncData(const std::string& name, const base::Value& value) {
  std::string serialized;
  JSONStringValueSerializer json(&serialized);
  json.Serialize(value);
  sync_pb::EntitySpecifics specifics;
  sync_pb::PreferenceSpecifics* pref =
      features::IsSplitSettingsSyncEnabled()
          ? specifics.mutable_os_preference()->mutable_preference()
          : specifics.mutable_preference();
  pref->set_name(name);
  pref->set_value(serialized);
  return syncer::SyncData::CreateRemoteData(
      specifics, syncer::ClientTagHash::FromHashed("unused"));
}

}  // anonymous namespace

namespace input_method {
namespace {

class MyMockInputMethodManager : public MockInputMethodManagerImpl {
 public:
  class State : public MockInputMethodManagerImpl::State {
   public:
    explicit State(MyMockInputMethodManager* manager)
        : MockInputMethodManagerImpl::State(manager), manager_(manager) {
      input_method_extensions_ = std::make_unique<InputMethodDescriptors>();
    }

    void ChangeInputMethod(const std::string& input_method_id,
                           bool show_message) override {
      manager_->last_input_method_id_ = input_method_id;
      const std::string current_input_method_on_pref =
          manager_->current_->GetValue();
      if (current_input_method_on_pref == input_method_id)
        return;
      manager_->previous_->SetValue(current_input_method_on_pref);
      manager_->current_->SetValue(input_method_id);
    }

    void GetInputMethodExtensions(InputMethodDescriptors* result) override {
      *result = *input_method_extensions_;
    }

    void AddInputMethodExtension(
        const std::string& id,
        const InputMethodDescriptors& descriptors,
        ui::IMEEngineHandlerInterface* instance) override {
      InputMethodDescriptor descriptor(
          id, std::string(), std::string(), std::string(),
          std::vector<std::string>(), false, GURL(), GURL());
      input_method_extensions_->push_back(descriptor);
    }

   protected:
    ~State() override {}

   private:
    MyMockInputMethodManager* const manager_;
    std::unique_ptr<InputMethodDescriptors> input_method_extensions_;
  };

  MyMockInputMethodManager(StringPrefMember* previous,
                           StringPrefMember* current)
      : previous_(previous),
        current_(current) {
    state_ = new State(this);
  }

  ~MyMockInputMethodManager() override {}

  std::string last_input_method_id_;

 private:
  StringPrefMember* previous_;
  StringPrefMember* current_;
};

}  // anonymous namespace
}  // namespace input_method

class PreferencesTest : public testing::Test {
 public:
  PreferencesTest() {}
  ~PreferencesTest() override {}

  void SetUp() override {
    profile_manager_ = std::make_unique<TestingProfileManager>(
        TestingBrowserProcess::GetGlobal());
    ASSERT_TRUE(profile_manager_->SetUp());

    auto* user_manager = new FakeChromeUserManager();
    user_manager_enabler_ = std::make_unique<user_manager::ScopedUserManager>(
        base::WrapUnique(user_manager));

    const char test_user_email[] = "test_user@example.com";
    const AccountId test_account_id(AccountId::FromUserEmail(test_user_email));
    test_user_ = user_manager->AddUser(test_account_id);
    user_manager->LoginUser(test_account_id);
    user_manager->SwitchActiveUser(test_account_id);

    test_profile_ = profile_manager_->CreateTestingProfile(
        chrome::kInitialProfile);
    pref_service_ = test_profile_->GetTestingPrefService();

    previous_input_method_.Init(
        prefs::kLanguagePreviousInputMethod, pref_service_);
    previous_input_method_.SetValue("KeyboardA");
    current_input_method_.Init(
        prefs::kLanguageCurrentInputMethod, pref_service_);
    current_input_method_.SetValue("KeyboardB");

    mock_manager_ = new input_method::MyMockInputMethodManager(
        &previous_input_method_, &current_input_method_);
    input_method::InitializeForTesting(mock_manager_);

    prefs_ = std::make_unique<Preferences>(mock_manager_);
  }

  void TearDown() override {
    input_method::Shutdown();
    // UserSessionManager doesn't listen to profile destruction, so make sure
    // the default IME state isn't still cached in case test_profile_ is
    // given the same address in the next test.
    UserSessionManager::GetInstance()->RemoveProfileForTesting(test_profile_);
  }

  void InitPreferences() {
    prefs_->InitUserPrefsForTesting(
        pref_service_, test_user_, mock_manager_->GetActiveIMEState());
    prefs_->SetInputMethodListForTesting();
  }

  content::BrowserTaskEnvironment task_environment_;
  std::unique_ptr<TestingProfileManager> profile_manager_;
  std::unique_ptr<user_manager::ScopedUserManager> user_manager_enabler_;
  std::unique_ptr<Preferences> prefs_;
  StringPrefMember previous_input_method_;
  StringPrefMember current_input_method_;

  // Not owned.
  const user_manager::User* test_user_;
  TestingProfile* test_profile_;
  sync_preferences::TestingPrefServiceSyncable* pref_service_;
  input_method::MyMockInputMethodManager* mock_manager_;

 private:
  DISALLOW_COPY_AND_ASSIGN(PreferencesTest);
};

TEST_F(PreferencesTest, TestUpdatePrefOnBrowserScreenDetails) {
  InitPreferences();

  // Confirm the current and previous input methods are unchanged.
  EXPECT_EQ("KeyboardA", previous_input_method_.GetValue());
  EXPECT_EQ("KeyboardB", current_input_method_.GetValue());
  EXPECT_EQ("KeyboardB", mock_manager_->last_input_method_id_);
}

class InputMethodPreferencesTest : public PreferencesTest {
 public:
  InputMethodPreferencesTest() {}
  ~InputMethodPreferencesTest() override {}

  void SetUp() override {
    PreferencesTest::SetUp();

    // Initialize pref members.
    preferred_languages_.Init(language::prefs::kPreferredLanguages,
                              pref_service_);
    preferred_languages_syncable_.Init(
        language::prefs::kPreferredLanguagesSyncable, pref_service_);
    preload_engines_.Init(prefs::kLanguagePreloadEngines, pref_service_);
    preload_engines_syncable_.Init(prefs::kLanguagePreloadEnginesSyncable,
                                   pref_service_);
    enabled_imes_.Init(prefs::kLanguageEnabledImes, pref_service_);
    enabled_imes_syncable_.Init(prefs::kLanguageEnabledImesSyncable,
                                pref_service_);

    // Initialize component and 3rd-party input method extensions.
    InitComponentExtensionIMEManager();
    input_method::InputMethodDescriptors descriptors;
    mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
        kIdentityIMEID, descriptors, nullptr);
    mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
        kToUpperIMEID, descriptors, nullptr);
    mock_manager_->GetActiveIMEState()->AddInputMethodExtension(
        kAPIArgumentIMEID, descriptors, nullptr);
  }

  void InitComponentExtensionIMEManager() {
    // Set our custom IME list on the mock delegate.
    input_method::MockComponentExtensionIMEManagerDelegate* mock_delegate =
        new input_method::MockComponentExtensionIMEManagerDelegate();
    mock_delegate->set_ime_list(CreateImeList());

    // Pass the mock delegate to a new ComponentExtensionIMEManager.
    std::unique_ptr<ComponentExtensionIMEManagerDelegate> delegate(
        mock_delegate);
    std::unique_ptr<ComponentExtensionIMEManager>
        component_extension_ime_manager(
            new ComponentExtensionIMEManager(std::move(delegate)));

    // Add the ComponentExtensionIMEManager to the mock InputMethodManager.
    mock_manager_->SetComponentExtensionIMEManager(
        std::move(component_extension_ime_manager));
  }

  std::vector<ComponentExtensionIME> CreateImeList() {
    std::vector<ComponentExtensionIME> ime_list;

    ComponentExtensionIME ext_xkb;
    ext_xkb.id = extension_ime_util::kXkbExtensionId;
    ext_xkb.description = "ext_xkb_description";
    ext_xkb.path = base::FilePath("ext_xkb_file_path");

    ComponentExtensionEngine ext_xkb_engine_se;
    ext_xkb_engine_se.engine_id = "xkb:se::swe";
    ext_xkb_engine_se.display_name = "xkb:se::swe";
    ext_xkb_engine_se.language_codes.push_back("sv");
    ext_xkb_engine_se.layout = "se";
    ext_xkb.engines.push_back(ext_xkb_engine_se);

    ComponentExtensionEngine ext_xkb_engine_jp;
    ext_xkb_engine_jp.engine_id = "xkb:jp::jpn";
    ext_xkb_engine_jp.display_name = "xkb:jp::jpn";
    ext_xkb_engine_jp.language_codes.push_back("ja");
    ext_xkb_engine_jp.layout = "jp";
    ext_xkb.engines.push_back(ext_xkb_engine_jp);

    ComponentExtensionEngine ext_xkb_engine_ru;
    ext_xkb_engine_ru.engine_id = "xkb:ru::rus";
    ext_xkb_engine_ru.display_name = "xkb:ru::rus";
    ext_xkb_engine_ru.language_codes.push_back("ru");
    ext_xkb_engine_ru.layout = "ru";
    ext_xkb.engines.push_back(ext_xkb_engine_ru);

    ime_list.push_back(ext_xkb);

    ComponentExtensionIME ext;
    ext.id = extension_ime_util::kMozcExtensionId;
    ext.description = "ext_description";
    ext.path = base::FilePath("ext_file_path");

    ComponentExtensionEngine ext_engine1;
    ext_engine1.engine_id = "nacl_mozc_us";
    ext_engine1.display_name = "ext_engine_1_display_name";
    ext_engine1.language_codes.push_back("ja");
    ext_engine1.layout = "us";
    ext.engines.push_back(ext_engine1);

    ComponentExtensionEngine ext_engine2;
    ext_engine2.engine_id = "nacl_mozc_jp";
    ext_engine2.display_name = "ext_engine_2_display_name";
    ext_engine2.language_codes.push_back("ja");
    ext_engine2.layout = "jp";
    ext.engines.push_back(ext_engine2);

    ime_list.push_back(ext);
    return ime_list;
  }

  // Helper function to set local language and input values.
  void SetLocalValues(const std::string& preferred_languages,
                      const std::string& preload_engines,
                      const std::string& enabled_imes) {
    preferred_languages_.SetValue(preferred_languages);
    preload_engines_.SetValue(preload_engines);
    enabled_imes_.SetValue(enabled_imes);
  }

  // Helper function to set global language and input values.
  void SetGlobalValues(const std::string& preferred_languages,
                       const std::string& preload_engines,
                       const std::string& enabled_imes) {
    preferred_languages_syncable_.SetValue(preferred_languages);
    preload_engines_syncable_.SetValue(preload_engines);
    enabled_imes_syncable_.SetValue(enabled_imes);
  }

  // Helper function to check local language and input values.
  void ExpectLocalValues(const std::string& preferred_languages,
                         const std::string& preload_engines,
                         const std::string& enabled_imes) {
    EXPECT_EQ(preferred_languages, preferred_languages_.GetValue());
    EXPECT_EQ(preload_engines, preload_engines_.GetValue());
    EXPECT_EQ(enabled_imes, enabled_imes_.GetValue());
  }

  // Helper function to check global language and input values.
  void ExpectGlobalValues(const std::string& preferred_languages,
                          const std::string& preload_engines,
                          const std::string& enabled_imes) {
    EXPECT_EQ(preferred_languages, preferred_languages_syncable_.GetValue());
    EXPECT_EQ(preload_engines, preload_engines_syncable_.GetValue());
    EXPECT_EQ(enabled_imes, enabled_imes_syncable_.GetValue());
  }

  // Translates engine IDs in a CSV string to input method IDs.
  std::string ToInputMethodIds(const std::string& value) {
    std::vector<std::string> tokens = base::SplitString(
        value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    std::transform(tokens.begin(), tokens.end(), tokens.begin(),
                   &extension_ime_util::GetInputMethodIDByEngineID);
    return base::JoinString(tokens, ",");
  }

  // Simulates the initial sync of preferences.
  syncer::SyncableService* SyncPreferences(
      const syncer::SyncDataList& sync_data_list) {
    // SplitSettingsSync moves IME prefs to be OS prefs.
    syncer::ModelType model_type = features::IsSplitSettingsSyncEnabled()
                                       ? syncer::OS_PREFERENCES
                                       : syncer::PREFERENCES;
    syncer::SyncableService* sync =
        pref_service_->GetSyncableService(model_type);
    sync->MergeDataAndStartSyncing(model_type, sync_data_list,
                                   std::unique_ptr<syncer::SyncChangeProcessor>(
                                       new syncer::FakeSyncChangeProcessor),
                                   std::unique_ptr<syncer::SyncErrorFactory>(
                                       new syncer::SyncErrorFactoryMock));
    content::RunAllTasksUntilIdle();
    return sync;
  }

  StringPrefMember preferred_languages_;
  StringPrefMember preferred_languages_syncable_;
  StringPrefMember preload_engines_;
  StringPrefMember preload_engines_syncable_;
  StringPrefMember enabled_imes_;
  StringPrefMember enabled_imes_syncable_;

 private:
  DISALLOW_COPY_AND_ASSIGN(InputMethodPreferencesTest);
};

// Tests that the server values are added to the values chosen at OOBE.
TEST_F(InputMethodPreferencesTest, TestOobeAndSync) {
  // Choose options at OOBE.
  pref_service_->SetBoolean(
      prefs::kLanguageShouldMergeInputMethods, true);
  SetLocalValues("es",
                 ToInputMethodIds("xkb:us:altgr-intl:eng"),
                 std::string());
  InitPreferences();

  // Suppose we add an input method before syncing starts.
  preload_engines_.SetValue(
      ToInputMethodIds("xkb:us:altgr-intl:eng,xkb:us:intl:eng"));

  // Create some values to come from the server.
  syncer::SyncDataList sync_data_list;
  sync_data_list.push_back(CreatePrefSyncData(
      language::prefs::kPreferredLanguagesSyncable, base::Value("ru,fi")));
  sync_data_list.push_back(CreatePrefSyncData(
      prefs::kLanguagePreloadEnginesSyncable, base::Value("xkb:se::swe")));
  sync_data_list.push_back(CreatePrefSyncData(
      prefs::kLanguageEnabledImesSyncable, base::Value(kIdentityIMEID)));

  // Sync for the first time.
  syncer::SyncableService* sync = SyncPreferences(sync_data_list);

  // Note that we expect the preload_engines to have been translated to input
  // method IDs during the merge.
  std::string expected_languages("es,ru,fi");
  std::string expected_preload_engines(
      "xkb:us:altgr-intl:eng,xkb:us:intl:eng,xkb:se::swe");
  std::string expected_extensions(kIdentityIMEID);
  {
    SCOPED_TRACE("Server values should have merged into local values.");
    ExpectLocalValues(
        expected_languages,
        ToInputMethodIds(expected_preload_engines),
        expected_extensions);
  }
  {
    SCOPED_TRACE("Server values should have been updated to local values.");
    ExpectGlobalValues(
        expected_languages, expected_preload_engines, expected_extensions);
  }

  // Update the global values from the server again.
  syncer::SyncChangeList change_list;
  change_list.push_back(syncer::SyncChange(
      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
      CreatePrefSyncData(language::prefs::kPreferredLanguagesSyncable,
                         base::Value("de"))));
  change_list.push_back(syncer::SyncChange(
      FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
      CreatePrefSyncData(prefs::kLanguagePreloadEnginesSyncable,
                         base::Value(ToInputMethodIds("xkb:de::ger")))));
  change_list.push_back(
      syncer::SyncChange(FROM_HERE, syncer::SyncChange::ACTION_UPDATE,
                         CreatePrefSyncData(prefs::kLanguageEnabledImesSyncable,
                                            base::Value(kToUpperIMEID))));
  sync->ProcessSyncChanges(FROM_HERE, change_list);
  content::RunAllTasksUntilIdle();

  {
    SCOPED_TRACE("Local preferences should have remained the same.");
    ExpectLocalValues(
        expected_languages,
        ToInputMethodIds(expected_preload_engines),
        expected_extensions);
  }
  // Change local preferences.
  SetLocalValues("ja", ToInputMethodIds("xkb:jp::jpn"), "ime2");
  {
    SCOPED_TRACE("Global preferences should have been updated.");
    ExpectGlobalValues("ja", "xkb:jp::jpn", "ime2");
  }
  content::RunAllTasksUntilIdle();
}

// Tests that logging in after sync has completed changes nothing.
TEST_F(InputMethodPreferencesTest, TestLogIn) {
  // Set up existing preference values.
  std::string languages("es");
  std::string preload_engines(ToInputMethodIds("xkb:es::spa"));
  std::string extensions(kIdentityIMEID);

  SetLocalValues(languages, preload_engines, extensions);
  SetGlobalValues(languages, preload_engines, extensions);
  pref_service_->SetBoolean(
      prefs::kLanguageShouldMergeInputMethods, false);
  InitPreferences();

  // Create some values to come from the server.
  syncer::SyncDataList sync_data_list;
  sync_data_list.push_back(CreatePrefSyncData(
      language::prefs::kPreferredLanguages, base::Value("ru,fi")));
  sync_data_list.push_back(
      CreatePrefSyncData(prefs::kLanguagePreloadEngines,
                         base::Value(ToInputMethodIds("xkb:ru::rus"))));
  sync_data_list.push_back(CreatePrefSyncData(prefs::kLanguageEnabledImes,
                                              base::Value(kIdentityIMEID)));

  // Sync.
  SyncPreferences(sync_data_list);
  {
    SCOPED_TRACE("Local preferences should have remained the same.");
    ExpectLocalValues(languages, preload_engines, extensions);
  }
  // Change local preferences.
  SetLocalValues("ja", ToInputMethodIds("xkb:jp::jpn"), kToUpperIMEID);
  content::RunAllTasksUntilIdle();
  {
    SCOPED_TRACE("Global preferences should have been updated.");
    ExpectGlobalValues("ja", "xkb:jp::jpn", kToUpperIMEID);
  }
}

// Tests that logging in with preferences from before a) XKB component
// extensions and b) the IME syncing logic doesn't overwrite settings.
TEST_F(InputMethodPreferencesTest, TestLogInLegacy) {
  // Simulate existing local preferences from M-36.
  SetLocalValues("es", "xkb:es::spa", kIdentityIMEID);
  InitPreferences();

  // Sync. Since this is an existing profile, the local values shouldn't change.
  syncer::SyncDataList sync_data_list;
  sync_data_list.push_back(CreatePrefSyncData(
      language::prefs::kPreferredLanguagesSyncable, base::Value("ru,fi")));
  sync_data_list.push_back(
      CreatePrefSyncData(prefs::kLanguagePreloadEnginesSyncable,
                         base::Value(ToInputMethodIds("xkb:ru::rus"))));
  sync_data_list.push_back(CreatePrefSyncData(
      prefs::kLanguageEnabledImesSyncable, base::Value(kToUpperIMEID)));

  // Sync.
  SyncPreferences(sync_data_list);
  {
    SCOPED_TRACE("Local preferences should have remained the same.");
    ExpectLocalValues("es", "xkb:es::spa", kIdentityIMEID);
  }
  {
    SCOPED_TRACE("Global preferences should have remained the same.");
    ExpectGlobalValues("ru,fi", ToInputMethodIds("xkb:ru::rus"), kToUpperIMEID);
  }
  // Change local preferences.
  SetLocalValues("ja", ToInputMethodIds("xkb:jp::jp"), kAPIArgumentIMEID);
  {
    SCOPED_TRACE("Global preferences should have been updated.");
    ExpectGlobalValues("ja", "xkb:jp::jp", kAPIArgumentIMEID);
  }
}

// Tests some edge cases: empty strings, lots of values, duplicates.
TEST_F(InputMethodPreferencesTest, MergeStressTest) {
  SetLocalValues("hr,lv,lt,es-419,he,el,da,ca,es,cs,bg",
                 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
                 std::string());
  pref_service_->SetBoolean(
      prefs::kLanguageShouldMergeInputMethods, true);
  InitPreferences();

  // Change input methods and languages before syncing starts.
  std::string local_extensions =
      kToUpperIMEID + std::string(",") +
      kAPIArgumentIMEID + std::string(",") +
      kIdentityIMEID;
  SetLocalValues(
      "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar",
      ToInputMethodIds("xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr"),
      local_extensions);

  // Create some tricky values to come from the server.
  syncer::SyncDataList sync_data_list;
  sync_data_list.push_back(
      CreatePrefSyncData(language::prefs::kPreferredLanguagesSyncable,
                         base::Value("ar,fi,es,de,ar")));
  sync_data_list.push_back(CreatePrefSyncData(
      prefs::kLanguagePreloadEnginesSyncable,
      base::Value(
          "nacl_mozc_us,xkb:ru::rus,xkb:ru::rus,xkb:es::spa,xkb:es::spa")));
  sync_data_list.push_back(CreatePrefSyncData(
      prefs::kLanguageEnabledImesSyncable, base::Value(std::string())));

  // Sync for the first time.
  SyncPreferences(sync_data_list);
  {
    SCOPED_TRACE("Server values should have merged into local values.");
    ExpectLocalValues(
        "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar,fi,de",
        ToInputMethodIds("xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr,"
                         "nacl_mozc_us,xkb:ru::rus"),
        local_extensions);
  }
  {
    SCOPED_TRACE("Server values should have incorporated local values.");
    ExpectGlobalValues(
        "en,es,ja,hr,lv,lt,es-419,he,el,da,ca,es,cs,bg,ar,fi,de",
        "xkb:es::spa,xkb:us:dvorak,xkb:ua::ukr,nacl_mozc_us,xkb:ru::rus",
        local_extensions);
  }
}

// Tests non-existent IDs.
TEST_F(InputMethodPreferencesTest, MergeInvalidValues) {
  SetLocalValues("es",
                 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
                 kIdentityIMEID);
  pref_service_->SetBoolean(
      prefs::kLanguageShouldMergeInputMethods, true);
  InitPreferences();

  // Create some valid and some non-existent IDs from the server.
  std::string preload_engines(
      "xkb:ru::rus,xkb:xy::xyz,"
      "_comp_ime_nothisisnotactuallyanextensionidxkb:es::spa," +
      ToInputMethodIds("xkb:jp::jpn"));
  syncer::SyncDataList sync_data_list;
  sync_data_list.push_back(
      CreatePrefSyncData(language::prefs::kPreferredLanguagesSyncable,
                         base::Value("klingon,en-US")));
  sync_data_list.push_back(CreatePrefSyncData(
      prefs::kLanguagePreloadEnginesSyncable, base::Value(preload_engines)));
  sync_data_list.push_back(CreatePrefSyncData(
      prefs::kLanguageEnabledImesSyncable, base::Value(kUnknownIMEID)));

  // Sync for the first time.
  SyncPreferences(sync_data_list);
  {
    SCOPED_TRACE("Only valid server values should have been merged in.");
    ExpectLocalValues(
        "es,en-US",
        ToInputMethodIds("xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:jp::jpn"),
        kIdentityIMEID);
  }
}

// Tests that we merge input methods even if syncing has started before
// initialization of Preferences.
TEST_F(InputMethodPreferencesTest, MergeAfterSyncing) {
  SetLocalValues("es",
                 ToInputMethodIds("xkb:es::spa,xkb:us::eng"),
                 kIdentityIMEID);
  pref_service_->SetBoolean(
      prefs::kLanguageShouldMergeInputMethods, true);

  // Create some valid and some non-existent IDs from the server.
  std::string preload_engines(
      "xkb:ru::rus,xkb:xy::xyz," + ToInputMethodIds("xkb:jp::jpn"));
  syncer::SyncDataList sync_data_list;
  sync_data_list.push_back(CreatePrefSyncData(
      language::prefs::kPreferredLanguagesSyncable, base::Value("en-US")));
  sync_data_list.push_back(CreatePrefSyncData(
      prefs::kLanguagePreloadEnginesSyncable, base::Value(preload_engines)));
  sync_data_list.push_back(CreatePrefSyncData(
      prefs::kLanguageEnabledImesSyncable, base::Value(kUnknownIMEID)));

  // Sync for the first time.
  SyncPreferences(sync_data_list);

  InitPreferences();
  content::RunAllTasksUntilIdle();

  {
    SCOPED_TRACE("Local values should have been merged on initialization.");
    ExpectLocalValues(
        "es,en-US",
        ToInputMethodIds("xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:jp::jpn"),
        kIdentityIMEID);
  }
  {
    SCOPED_TRACE(
        "Syncable values should have added local values on initialization.");
    ExpectGlobalValues(
        "es,en-US",
        "xkb:es::spa,xkb:us::eng,xkb:ru::rus,xkb:xy::xyz," +
            ToInputMethodIds("xkb:jp::jpn"),
        std::string(kIdentityIMEID) + "," + kUnknownIMEID);
  }
}

}  // namespace chromeos
