// Copyright 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 <stddef.h>
#include <stdint.h>

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

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/test/bind_test_util.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/webdata/autofill_change.h"
#include "components/autofill/core/browser/webdata/autofill_profile_data_type_controller.h"
#include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/common/autofill_prefs.h"
#include "components/browser_sync/abstract_profile_sync_service_test.h"
#include "components/browser_sync/profile_sync_service.h"
#include "components/browser_sync/test_profile_sync_service.h"
#include "components/sync/base/model_type.h"
#include "components/sync/driver/data_type_controller.h"
#include "components/sync/driver/data_type_manager_impl.h"
#include "components/sync/driver/sync_api_component_factory_mock.h"
#include "components/sync/driver/sync_client_mock.h"
#include "components/sync/engine/data_type_debug_info_listener.h"
#include "components/sync/engine/sequenced_model_worker.h"
#include "components/sync/protocol/autofill_specifics.pb.h"
#include "components/sync/syncable/mutable_entry.h"
#include "components/sync/syncable/read_node.h"
#include "components/sync/syncable/read_transaction.h"
#include "components/sync/syncable/syncable_write_transaction.h"
#include "components/sync/syncable/write_node.h"
#include "components/sync/syncable/write_transaction.h"
#include "components/sync_preferences/pref_service_syncable.h"
#include "components/version_info/version_info.h"
#include "components/webdata/common/web_database.h"
#include "components/webdata_services/web_data_service_test_util.h"
#include "services/identity/public/cpp/identity_test_utils.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using autofill::AutofillChange;
using autofill::AutofillChangeList;
using autofill::AutofillKey;
using autofill::AutofillProfile;
using autofill::AutofillProfileChange;
using autofill::AutofillProfileSyncableService;
using autofill::AutofillTable;
using autofill::AutofillWebDataService;
using autofill::NAME_FULL;
using autofill::PersonalDataManager;
using autofill::ServerFieldType;
using base::ASCIIToUTF16;
using base::Time;
using base::TimeDelta;
using base::WaitableEvent;
using syncer::AUTOFILL_PROFILE;
using syncer::BaseNode;
using syncer::syncable::CREATE;
using syncer::syncable::GET_TYPE_ROOT;
using syncer::syncable::MutableEntry;
using syncer::syncable::UNITTEST;
using syncer::syncable::WriterTag;
using syncer::syncable::WriteTransaction;
using testing::_;
using testing::ByMove;
using testing::DoAll;
using testing::ElementsAre;
using testing::Not;
using testing::Return;
using testing::SetArgPointee;

namespace browser_sync {

namespace {

void RegisterAutofillPrefs(user_prefs::PrefRegistrySyncable* registry) {
  registry->RegisterBooleanPref(autofill::prefs::kAutofillCreditCardEnabled,
                                true);
  registry->RegisterBooleanPref(autofill::prefs::kAutofillProfileEnabled, true);
  registry->RegisterBooleanPref(autofill::prefs::kAutofillWalletImportEnabled,
                                true);
  registry->RegisterIntegerPref(autofill::prefs::kAutofillLastVersionDeduped,
                                atoi(version_info::GetVersionNumber().c_str()));
  registry->RegisterIntegerPref(autofill::prefs::kAutofillLastVersionValidated,
                                atoi(version_info::GetVersionNumber().c_str()));
  registry->RegisterDoublePref(autofill::prefs::kAutofillBillingCustomerNumber,
                               0.0);
  registry->RegisterBooleanPref(
      autofill::prefs::kAutofillJapanCityFieldMigrated, true);
  registry->RegisterBooleanPref(autofill::prefs::kAutofillOrphanRowsRemoved,
                                true);
  registry->RegisterIntegerPref(
      autofill::prefs::kAutofillLastVersionDisusedAddressesDeleted, 0);
  registry->RegisterIntegerPref(
      autofill::prefs::kAutofillLastVersionDisusedCreditCardsDeleted, 0);
  registry->RegisterStringPref(
      autofill::prefs::kAutofillProfileValidity, "",
      user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
}

void RunAndSignal(base::OnceClosure cb, WaitableEvent* event) {
  std::move(cb).Run();
  event->Signal();
}

}  // namespace

class AutofillTableMock : public AutofillTable {
 public:
  AutofillTableMock() {}
  MOCK_METHOD2(RemoveFormElement,
               bool(const base::string16& name,
                    const base::string16& value));  // NOLINT
  MOCK_METHOD4(GetAutofillTimestamps,
               bool(const base::string16& name,  // NOLINT
                    const base::string16& value,
                    Time* date_created,
                    Time* date_last_used));
  MOCK_METHOD1(GetAutofillProfiles,
               bool(std::vector<std::unique_ptr<AutofillProfile>>*));  // NOLINT
  MOCK_METHOD1(UpdateAutofillProfile, bool(const AutofillProfile&));   // NOLINT
  MOCK_METHOD1(AddAutofillProfile, bool(const AutofillProfile&));      // NOLINT
  MOCK_METHOD1(RemoveAutofillProfile, bool(const std::string&));       // NOLINT

  // TODO(crbug.com/904390): Remove when the investigation is over.
  MOCK_CONST_METHOD1(
      GetServerProfiles,
      bool(std::vector<std::unique_ptr<AutofillProfile>>*));  // NOLINT
};

MATCHER_P(MatchProfiles, profile, "") {
  return (profile.Compare(arg) == 0);
}

ACTION_P(LoadAutofillProfiles, datafunc) {
  std::vector<std::unique_ptr<AutofillProfile>> profiles =
      std::move(datafunc());
  arg0->swap(profiles);
}

class WebDatabaseFake : public WebDatabase {
 public:
  explicit WebDatabaseFake(AutofillTable* autofill_table) {
    AddTable(autofill_table);
  }
};

class FakeAutofillBackend : public autofill::AutofillWebDataBackend {
 public:
  FakeAutofillBackend(
      WebDatabase* web_database,
      const base::RepeatingClosure& on_changed,
      const base::RepeatingCallback<void(syncer::ModelType)>& on_sync_started,
      const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner)
      : web_database_(web_database),
        on_changed_(on_changed),
        on_sync_started_(on_sync_started),
        ui_task_runner_(ui_task_runner) {}

  ~FakeAutofillBackend() override {}
  WebDatabase* GetDatabase() override { return web_database_; }
  void AddObserver(
      autofill::AutofillWebDataServiceObserverOnDBSequence* observer) override {
  }
  void RemoveObserver(
      autofill::AutofillWebDataServiceObserverOnDBSequence* observer) override {
  }
  void RemoveExpiredFormElements() override {}

  void NotifyOfAutofillProfileChanged(
      const autofill::AutofillProfileChange& change) override {}
  void NotifyOfCreditCardChanged(
      const autofill::CreditCardChange& change) override {}
  void NotifyOfMultipleAutofillChanges() override {
    DCHECK(!ui_task_runner_->RunsTasksInCurrentSequence());
    ui_task_runner_->PostTask(FROM_HERE, on_changed_);
  }
  void NotifyThatSyncHasStarted(syncer::ModelType model_type) override {
    DCHECK(!ui_task_runner_->RunsTasksInCurrentSequence());
    ui_task_runner_->PostTask(FROM_HERE,
                              base::BindOnce(on_sync_started_, model_type));
  }

 private:
  WebDatabase* web_database_;
  base::RepeatingClosure on_changed_;
  base::RepeatingCallback<void(syncer::ModelType)> on_sync_started_;
  const scoped_refptr<base::SequencedTaskRunner> ui_task_runner_;
};

class ProfileSyncServiceAutofillTest;

class TokenWebDataServiceFake : public TokenWebData {
 public:
  TokenWebDataServiceFake(
      const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
      const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner)
      : TokenWebData(ui_task_runner, db_task_runner) {}

  bool IsDatabaseLoaded() override { return true; }

  AutofillWebDataService::Handle GetAllTokens(
      WebDataServiceConsumer* consumer) override {
    // TODO(tim): It would be nice if WebDataService was injected on
    // construction of ProfileOAuth2TokenService rather than fetched by
    // Initialize so that this isn't necessary (we could pass a null service).
    // We currently do return it via EXPECT_CALLs, but without depending on
    // order-of-initialization (which seems way more fragile) we can't tell
    // which component is asking at what time, and some components in these
    // Autofill tests require a WebDataService.
    return 0;
  }

 private:
  ~TokenWebDataServiceFake() override {}

  DISALLOW_COPY_AND_ASSIGN(TokenWebDataServiceFake);
};

class WebDataServiceFake : public AutofillWebDataService {
 public:
  WebDataServiceFake(
      const scoped_refptr<base::SingleThreadTaskRunner>& ui_task_runner,
      const scoped_refptr<base::SingleThreadTaskRunner>& db_task_runner)
      : AutofillWebDataService(ui_task_runner, db_task_runner),
        web_database_(nullptr),
        autofill_profile_syncable_service_(nullptr),
        syncable_service_created_or_destroyed_(
            base::WaitableEvent::ResetPolicy::AUTOMATIC,
            base::WaitableEvent::InitialState::NOT_SIGNALED),
        db_task_runner_(db_task_runner),
        ui_task_runner_(ui_task_runner) {}

  void SetDatabase(WebDatabase* web_database) { web_database_ = web_database; }

  void StartSyncableService() {
    // The |autofill_profile_syncable_service_| must be constructed on the DB
    // sequence.
    const base::RepeatingClosure& on_changed_callback = base::BindRepeating(
        &WebDataServiceFake::NotifyAutofillMultipleChangedOnUISequence,
        AsWeakPtr());
    const base::RepeatingCallback<void(syncer::ModelType)>&
        on_sync_started_callback = base::BindRepeating(
            &WebDataServiceFake::NotifySyncStartedOnUISequence, AsWeakPtr());

    db_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&WebDataServiceFake::CreateSyncableService,
                                  base::Unretained(this), on_changed_callback,
                                  std::move(on_sync_started_callback)));
    syncable_service_created_or_destroyed_.Wait();
  }

  void ShutdownSyncableService() {
    // The |autofill_profile_syncable_service_| must be destructed on the DB
    // sequence.
    db_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&WebDataServiceFake::DestroySyncableService,
                                  base::Unretained(this)));
    syncable_service_created_or_destroyed_.Wait();
  }

  bool IsDatabaseLoaded() override { return true; }

  WebDatabase* GetDatabase() override { return web_database_; }

  void OnAutofillProfileChanged(const AutofillProfileChange& changes) {
    WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL,
                        base::WaitableEvent::InitialState::NOT_SIGNALED);

    base::OnceClosure notify_cb = base::BindOnce(
        &AutofillProfileSyncableService::AutofillProfileChanged,
        base::Unretained(autofill_profile_syncable_service_), changes);
    db_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&RunAndSignal, std::move(notify_cb), &event));
    event.Wait();
  }

 private:
  ~WebDataServiceFake() override {}

  void CreateSyncableService(
      const base::RepeatingClosure& on_changed_callback,
      const base::RepeatingCallback<void(syncer::ModelType)>& on_sync_started) {
    ASSERT_TRUE(db_task_runner_->RunsTasksInCurrentSequence());
    // These services are deleted in DestroySyncableService().
    backend_ = std::make_unique<FakeAutofillBackend>(
        GetDatabase(), on_changed_callback, on_sync_started,
        ui_task_runner_.get());
    AutofillProfileSyncableService::CreateForWebDataServiceAndBackend(
        this, backend_.get(), "en-US");

    autofill_profile_syncable_service_ =
        AutofillProfileSyncableService::FromWebDataService(this);

    syncable_service_created_or_destroyed_.Signal();
  }

  void DestroySyncableService() {
    ASSERT_TRUE(db_task_runner_->RunsTasksInCurrentSequence());
    autofill_profile_syncable_service_ = nullptr;
    backend_.reset();
    syncable_service_created_or_destroyed_.Signal();
  }

  WebDatabase* web_database_;
  AutofillProfileSyncableService* autofill_profile_syncable_service_;
  std::unique_ptr<autofill::AutofillWebDataBackend> backend_;

  WaitableEvent syncable_service_created_or_destroyed_;

  const scoped_refptr<base::SingleThreadTaskRunner> db_task_runner_;
  const scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;

  DISALLOW_COPY_AND_ASSIGN(WebDataServiceFake);
};

ACTION_P(ReturnNewDataTypeManagerWithDebugListener, debug_listener) {
  return std::make_unique<syncer::DataTypeManagerImpl>(arg0, debug_listener,
                                                       arg2, arg3, arg4, arg5);
}

class MockPersonalDataManager : public PersonalDataManager {
 public:
  MockPersonalDataManager() : PersonalDataManager("en-US") {}
  MOCK_CONST_METHOD0(IsDataLoaded, bool());
  MOCK_METHOD0(LoadProfiles, void());
  MOCK_METHOD0(LoadCreditCards, void());
  MOCK_METHOD0(LoadPaymentsCustomerData, void());
  MOCK_METHOD0(Refresh, void());
};

class AddAutofillProfileHelper;

class ProfileSyncServiceAutofillTest
    : public AbstractProfileSyncServiceTest,
      public syncer::DataTypeDebugInfoListener {
 public:
  // DataTypeDebugInfoListener implementation.
  void OnDataTypeConfigureComplete(
      const std::vector<syncer::DataTypeConfigurationStats>&
          configuration_stats) override {
    for (const syncer::DataTypeConfigurationStats& stat : configuration_stats) {
      if (stat.model_type == syncer::AUTOFILL_PROFILE) {
        association_stats_ = stat.association_stats;
        return;
      }
    }
    ASSERT_TRUE(false) << "Autofill profile type did not get configured!";
  }

 protected:
  ProfileSyncServiceAutofillTest() : debug_ptr_factory_(this) {
    autofill::CountryNames::SetLocaleString("en-US");
    RegisterAutofillPrefs(
        profile_sync_service_bundle()->pref_service()->registry());

    data_type_thread()->Start();

    web_database_ = std::make_unique<WebDatabaseFake>(&autofill_table_);
    web_data_wrapper_ = std::make_unique<MockWebDataServiceWrapper>(
        new WebDataServiceFake(base::ThreadTaskRunnerHandle::Get(),
                               data_type_thread()->task_runner()),
        new TokenWebDataServiceFake(base::ThreadTaskRunnerHandle::Get(),
                                    data_type_thread()->task_runner()));
    web_data_service_ = static_cast<WebDataServiceFake*>(
        web_data_wrapper_->GetProfileAutofillWebData().get());
    web_data_service_->SetDatabase(web_database_.get());

    personal_data_manager_ = std::make_unique<MockPersonalDataManager>();

    EXPECT_CALL(personal_data_manager(), LoadProfiles());
    EXPECT_CALL(personal_data_manager(), LoadCreditCards());
    EXPECT_CALL(personal_data_manager(), LoadPaymentsCustomerData());

    personal_data_manager_->Init(web_data_service_,
                                 /*account_database=*/nullptr,
                                 profile_sync_service_bundle()->pref_service(),
                                 /*identity_manager=*/nullptr,
                                 /*client_profile_validator=*/nullptr,
                                 /*history_service=*/nullptr,
                                 /*is_off_the_record=*/false);

    web_data_service_->StartSyncableService();
  }

  ~ProfileSyncServiceAutofillTest() override {
    web_data_service_->ShutdownOnUISequence();
    web_data_service_->ShutdownSyncableService();
    web_data_wrapper_->Shutdown();
    web_data_service_ = nullptr;
    web_data_wrapper_.reset();
    web_database_.reset();
    // Shut down the service explicitly before some data members from this
    // test it needs will be deleted.
    sync_service()->Shutdown();
  }

  int GetSyncCount() {
    syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare());
    syncer::ReadNode node(&trans);
    if (node.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK)
      return 0;
    return node.GetTotalNodeCount() - 1;
  }

  void StartAutofillProfileSyncService(base::OnceClosure callback) {
    profile_sync_service_bundle()
        ->identity_test_env()
        ->MakePrimaryAccountAvailable("test_user@gmail.com");

    std::unique_ptr<syncer::SyncClientMock> sync_client =
        profile_sync_service_bundle()->CreateSyncClientMock();
    syncer::SyncClientMock* sync_client_copy = sync_client.get();
    CreateSyncService(std::move(sync_client), std::move(callback));

    syncer::DataTypeController::TypeVector controllers;
    controllers.push_back(std::make_unique<AutofillProfileDataTypeController>(
        data_type_thread()->task_runner(), /*dump_stack=*/base::DoNothing(),
        sync_service(), sync_client_copy,
        base::BindLambdaForTesting([&]() -> autofill::PersonalDataManager* {
          return personal_data_manager_.get();
        }),
        web_data_service_));

    ON_CALL(*sync_client_copy, GetSyncableServiceForType(AUTOFILL_PROFILE))
        .WillByDefault(testing::Invoke([=](syncer::ModelType) {
          return AutofillProfileSyncableService::FromWebDataService(
                     web_data_service_.get())
              ->AsWeakPtr();
        }));
    ON_CALL(*sync_client_copy, CreateDataTypeControllers(_))
        .WillByDefault(Return(ByMove(std::move(controllers))));
    ON_CALL(*sync_client_copy, CreateModelWorkerForGroup(syncer::GROUP_DB))
        .WillByDefault(
            Return(base::MakeRefCounted<syncer::SequencedModelWorker>(
                data_type_thread()->task_runner(), syncer::GROUP_DB)));

    ON_CALL(*profile_sync_service_bundle()->component_factory(),
            CreateDataTypeManager(_, _, _, _, _, _))
        .WillByDefault(ReturnNewDataTypeManagerWithDebugListener(
            syncer::MakeWeakHandle(debug_ptr_factory_.GetWeakPtr())));

    EXPECT_CALL(personal_data_manager(), IsDataLoaded())
        .WillRepeatedly(Return(true));

    sync_service()->Initialize();
    base::RunLoop().Run();

    // It's possible this test triggered an unrecoverable error, in which case
    // we can't get the sync count.
    if (sync_service()->IsSyncFeatureActive()) {
      EXPECT_EQ(GetSyncCount(),
                association_stats_.num_sync_items_after_association);
    }
    EXPECT_EQ(association_stats_.num_sync_items_after_association,
              association_stats_.num_sync_items_before_association +
                  association_stats_.num_sync_items_added -
                  association_stats_.num_sync_items_deleted);
  }

  bool AddAutofillSyncNode(const AutofillProfile& profile) {
    syncer::WriteTransaction trans(FROM_HERE, sync_service()->GetUserShare());
    syncer::WriteNode node(&trans);
    std::string tag = profile.guid();
    syncer::WriteNode::InitUniqueByCreationResult result =
        node.InitUniqueByCreation(AUTOFILL_PROFILE, tag);
    if (result != syncer::WriteNode::INIT_SUCCESS)
      return false;

    sync_pb::EntitySpecifics specifics;
    AutofillProfileSyncableService::WriteAutofillProfile(profile, &specifics);
    node.SetEntitySpecifics(specifics);
    return true;
  }

  bool GetAutofillProfilesFromSyncDBUnderProfileNode(
      std::vector<AutofillProfile>* profiles) {
    syncer::ReadTransaction trans(FROM_HERE, sync_service()->GetUserShare());
    syncer::ReadNode autofill_root(&trans);
    if (autofill_root.InitTypeRoot(AUTOFILL_PROFILE) != BaseNode::INIT_OK) {
      return false;
    }

    int64_t child_id = autofill_root.GetFirstChildId();
    while (child_id != syncer::kInvalidId) {
      syncer::ReadNode child_node(&trans);
      if (child_node.InitByIdLookup(child_id) != BaseNode::INIT_OK)
        return false;

      const sync_pb::AutofillProfileSpecifics& autofill(
          child_node.GetEntitySpecifics().autofill_profile());
      AutofillProfile p;
      p.set_guid(autofill.guid());
      AutofillProfileSyncableService::OverwriteProfileWithServerData(autofill,
                                                                     &p);
      profiles->push_back(p);
      child_id = child_node.GetSuccessorId();
    }
    return true;
  }

  void SetIdleChangeProcessorExpectations() {
    EXPECT_CALL(autofill_table_, RemoveFormElement(_, _)).Times(0);
    EXPECT_CALL(autofill_table_, GetAutofillTimestamps(_, _, _, _)).Times(0);
  }

  AutofillTableMock& autofill_table() { return autofill_table_; }

  MockPersonalDataManager& personal_data_manager() {
    return *personal_data_manager_;
  }

  WebDataServiceFake* web_data_service() { return web_data_service_.get(); }

 private:
  friend class AddAutofillProfileHelper;

  AutofillTableMock autofill_table_;
  std::unique_ptr<WebDatabaseFake> web_database_;
  std::unique_ptr<MockWebDataServiceWrapper> web_data_wrapper_;
  scoped_refptr<WebDataServiceFake> web_data_service_;
  std::unique_ptr<MockPersonalDataManager> personal_data_manager_;
  syncer::DataTypeAssociationStats association_stats_;
  base::WeakPtrFactory<DataTypeDebugInfoListener> debug_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceAutofillTest);
};

class AddAutofillProfileHelper {
 public:
  AddAutofillProfileHelper(ProfileSyncServiceAutofillTest* test,
                           const std::vector<AutofillProfile>& entries)
      : callback_(base::BindOnce(&AddAutofillProfileHelper::AddAutofillCallback,
                                 base::Unretained(this),
                                 test,
                                 entries)),
        success_(false) {}

  base::OnceClosure callback() { return std::move(callback_); }
  bool success() { return success_; }

 private:
  void AddAutofillCallback(ProfileSyncServiceAutofillTest* test,
                           const std::vector<AutofillProfile>& entries) {
    if (!test->CreateRoot(AUTOFILL_PROFILE))
      return;

    for (size_t i = 0; i < entries.size(); ++i) {
      if (!test->AddAutofillSyncNode(entries[i]))
        return;
    }
    success_ = true;
  }

  base::OnceClosure callback_;
  bool success_;
};

TEST_F(ProfileSyncServiceAutofillTest, HasProfileEmptySync) {
  std::vector<std::unique_ptr<AutofillProfile>> profiles;
  std::vector<AutofillProfile> expected_profiles;
  std::unique_ptr<AutofillProfile> profile0 =
      std::make_unique<AutofillProfile>();
  autofill::test::SetProfileInfoWithGuid(
      profile0.get(), "54B3F9AA-335E-4F71-A27D-719C41564230", "Billing",
      "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.",
      "unit 5", "Hollywood", "CA", "91601", "US", "12345678910");
  expected_profiles.push_back(*profile0);
  profiles.push_back(std::move(profile0));
  auto profile_returner = [&profiles]() { return std::move(profiles); };
  EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
      .WillOnce(DoAll(LoadAutofillProfiles(profile_returner), Return(true)));
  EXPECT_CALL(personal_data_manager(), Refresh());
  SetIdleChangeProcessorExpectations();
  CreateRootHelper create_root(this, AUTOFILL_PROFILE);
  StartAutofillProfileSyncService(create_root.callback());
  ASSERT_TRUE(create_root.success());
  std::vector<AutofillProfile> sync_profiles;
  ASSERT_TRUE(GetAutofillProfilesFromSyncDBUnderProfileNode(&sync_profiles));
  EXPECT_EQ(1U, sync_profiles.size());
  EXPECT_EQ(0, expected_profiles[0].Compare(sync_profiles[0]));
}

TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSyncMergeProfile) {
  AutofillProfile sync_profile;
  autofill::test::SetProfileInfoWithGuid(
      &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
      "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.",
      "unit 5", "Hollywood", "CA", "91601", "US", "12345678910");

  std::unique_ptr<AutofillProfile> native_profile =
      std::make_unique<AutofillProfile>();
  autofill::test::SetProfileInfoWithGuid(
      native_profile.get(), "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
      "Alicia", "Saenz", "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
      "Orlando", "FL", "32801", "US", "19482937549");

  std::vector<std::unique_ptr<AutofillProfile>> native_profiles;
  native_profiles.push_back(std::move(native_profile));
  auto profile_returner = [&native_profiles]() {
    return std::move(native_profiles);
  };
  EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
      .WillOnce(DoAll(LoadAutofillProfiles(profile_returner), Return(true)));

  std::vector<AutofillProfile> sync_profiles;
  sync_profiles.push_back(sync_profile);
  AddAutofillProfileHelper add_autofill(this, sync_profiles);

  EXPECT_CALL(autofill_table(),
              UpdateAutofillProfile(MatchProfiles(sync_profile)))
      .WillOnce(Return(true));
  EXPECT_CALL(personal_data_manager(), Refresh());
  StartAutofillProfileSyncService(add_autofill.callback());
  ASSERT_TRUE(add_autofill.success());

  std::vector<AutofillProfile> new_sync_profiles;
  ASSERT_TRUE(
      GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
  ASSERT_EQ(1U, new_sync_profiles.size());
  EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
}

// Tests that a sync with a new native profile that matches a more recent new
// sync profile but with less information results in the native profile being
// deleted and replaced by the sync profile with merged usage stats.
TEST_F(
    ProfileSyncServiceAutofillTest,
    HasNativeHasSyncMergeSimilarProfileCombine_SyncHasMoreInfoAndMoreRecent) {
  // Create two almost identical profiles. The GUIDs are different and the
  // native profile has no value for company name.
  AutofillProfile sync_profile;
  autofill::test::SetProfileInfoWithGuid(
      &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
      "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.",
      "unit 5", "Hollywood", "CA", "91601", "US", "12345678910");
  sync_profile.set_use_date(base::Time::FromTimeT(4321));

  std::unique_ptr<AutofillProfile> native_profile =
      std::make_unique<AutofillProfile>();
  autofill::test::SetProfileInfoWithGuid(
      native_profile.get(), "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing",
      "Mitchell", "Morrison", "johnwayne@me.xyz", "", "123 Zoo St.", "unit 5",
      "Hollywood", "CA", "91601", "US", "12345678910");
  native_profile->set_use_date(base::Time::FromTimeT(1234));

  AutofillProfile expected_profile(sync_profile);
  expected_profile.SetRawInfo(NAME_FULL,
                              ASCIIToUTF16("Billing Mitchell Morrison"));
  expected_profile.set_use_count(1);

  std::vector<std::unique_ptr<AutofillProfile>> native_profiles;
  native_profiles.push_back(std::move(native_profile));
  auto profile_returner = [&native_profiles]() {
    return std::move(native_profiles);
  };
  EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
      .WillOnce(DoAll(LoadAutofillProfiles(profile_returner), Return(true)));
  EXPECT_CALL(autofill_table(),
              AddAutofillProfile(MatchProfiles(expected_profile)))
      .WillOnce(Return(true));
  EXPECT_CALL(autofill_table(),
              RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF"))
      .WillOnce(Return(true));
  std::vector<AutofillProfile> sync_profiles;
  sync_profiles.push_back(sync_profile);
  AddAutofillProfileHelper add_autofill(this, sync_profiles);

  EXPECT_CALL(personal_data_manager(), Refresh());
  // Adds all entries in |sync_profiles| to sync.
  StartAutofillProfileSyncService(add_autofill.callback());
  ASSERT_TRUE(add_autofill.success());

  std::vector<AutofillProfile> new_sync_profiles;
  ASSERT_TRUE(
      GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
  ASSERT_EQ(1U, new_sync_profiles.size());
  // Check that key fields are the same.
  EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(sync_profile, "en-US"));
  // Make sure the additional information from the sync profile was kept.
  EXPECT_EQ(ASCIIToUTF16("Fox"),
            new_sync_profiles[0].GetRawInfo(ServerFieldType::COMPANY_NAME));
  // Check that the latest use date is saved.
  EXPECT_EQ(base::Time::FromTimeT(4321), new_sync_profiles[0].use_date());
  // Check that the use counts were added (default value is 1).
  EXPECT_EQ(1U, new_sync_profiles[0].use_count());
}

// Tests that a sync with a new native profile that matches an older new sync
// profile but with less information results in the native profile being deleted
// and replaced by the sync profile with merged usage stats.
TEST_F(ProfileSyncServiceAutofillTest,
       HasNativeHasSyncMergeSimilarProfileCombine_SyncHasMoreInfoAndOlder) {
  // Create two almost identical profiles. The GUIDs are different and the
  // native profile has no value for company name.
  AutofillProfile sync_profile;
  autofill::test::SetProfileInfoWithGuid(
      &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
      "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.",
      "unit 5", "Hollywood", "CA", "91601", "US", "12345678910");
  sync_profile.set_use_date(base::Time::FromTimeT(1234));

  std::unique_ptr<AutofillProfile> native_profile =
      std::make_unique<AutofillProfile>();
  autofill::test::SetProfileInfoWithGuid(
      native_profile.get(), "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing",
      "Mitchell", "Morrison", "johnwayne@me.xyz", "", "123 Zoo St.", "unit 5",
      "Hollywood", "CA", "91601", "US", "12345678910");
  native_profile->set_use_date(base::Time::FromTimeT(4321));

  AutofillProfile expected_profile(sync_profile);
  expected_profile.SetRawInfo(NAME_FULL,
                              ASCIIToUTF16("Billing Mitchell Morrison"));
  expected_profile.set_use_count(1);
  expected_profile.set_use_date(native_profile->use_date());

  std::vector<std::unique_ptr<AutofillProfile>> native_profiles;
  native_profiles.push_back(std::move(native_profile));
  auto profile_returner = [&native_profiles]() {
    return std::move(native_profiles);
  };
  EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
      .WillOnce(DoAll(LoadAutofillProfiles(profile_returner), Return(true)));
  EXPECT_CALL(autofill_table(),
              AddAutofillProfile(MatchProfiles(expected_profile)))
      .WillOnce(Return(true));
  EXPECT_CALL(autofill_table(),
              RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF"))
      .WillOnce(Return(true));
  std::vector<AutofillProfile> sync_profiles;
  sync_profiles.push_back(sync_profile);
  AddAutofillProfileHelper add_autofill(this, sync_profiles);

  EXPECT_CALL(personal_data_manager(), Refresh());
  // Adds all entries in |sync_profiles| to sync.
  StartAutofillProfileSyncService(add_autofill.callback());
  ASSERT_TRUE(add_autofill.success());

  std::vector<AutofillProfile> new_sync_profiles;
  ASSERT_TRUE(
      GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
  ASSERT_EQ(1U, new_sync_profiles.size());
  // Check that key fields are the same.
  EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(sync_profile, "en-US"));
  // Make sure the additional information from the sync profile was kept.
  EXPECT_EQ(ASCIIToUTF16("Fox"),
            new_sync_profiles[0].GetRawInfo(ServerFieldType::COMPANY_NAME));
  // Check that the latest use date is saved.
  EXPECT_EQ(base::Time::FromTimeT(4321), new_sync_profiles[0].use_date());
  // Check that the use counts were added (default value is 1).
  EXPECT_EQ(1U, new_sync_profiles[0].use_count());
}

// Tests that a sync with a new native profile that matches an a new sync
// profile but with more information results in the native profile being deleted
// and replaced by the sync profile with the native profiles additional
// information merged in. The merge should happen even if the sync profile is
// more recent.
TEST_F(ProfileSyncServiceAutofillTest,
       HasNativeHasSyncMergeSimilarProfileCombine_NativeHasMoreInfo) {
  // Create two almost identical profiles. The GUIDs are different and the
  // sync profile has no value for company name.
  AutofillProfile sync_profile;
  autofill::test::SetProfileInfoWithGuid(
      &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
      "Mitchell", "Morrison", "johnwayne@me.xyz", "", "123 Zoo St.", "unit 5",
      "Hollywood", "CA", "91601", "US", "12345678910");
  sync_profile.set_use_date(base::Time::FromTimeT(4321));

  std::unique_ptr<AutofillProfile> native_profile =
      std::make_unique<AutofillProfile>();
  autofill::test::SetProfileInfoWithGuid(
      native_profile.get(), "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing",
      "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.",
      "unit 5", "Hollywood", "CA", "91601", "US", "12345678910");
  native_profile->set_use_date(base::Time::FromTimeT(1234));

  AutofillProfile expected_profile(*native_profile);
  expected_profile.SetRawInfo(NAME_FULL,
                              ASCIIToUTF16("Billing Mitchell Morrison"));
  expected_profile.set_use_date(sync_profile.use_date());
  expected_profile.set_use_count(1);

  std::vector<std::unique_ptr<AutofillProfile>> native_profiles;
  native_profiles.push_back(std::move(native_profile));
  auto profile_returner = [&native_profiles]() {
    return std::move(native_profiles);
  };
  EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
      .WillOnce(DoAll(LoadAutofillProfiles(profile_returner), Return(true)));
  EXPECT_CALL(autofill_table(),
              AddAutofillProfile(MatchProfiles(expected_profile)))
      .WillOnce(Return(true));
  EXPECT_CALL(autofill_table(),
              RemoveAutofillProfile("23355099-1170-4B71-8ED4-144470CC9EBF"))
      .WillOnce(Return(true));
  std::vector<AutofillProfile> sync_profiles;
  sync_profiles.push_back(sync_profile);
  AddAutofillProfileHelper add_autofill(this, sync_profiles);

  EXPECT_CALL(personal_data_manager(), Refresh());
  // Adds all entries in |sync_profiles| to sync.
  StartAutofillProfileSyncService(add_autofill.callback());
  ASSERT_TRUE(add_autofill.success());

  std::vector<AutofillProfile> new_sync_profiles;
  ASSERT_TRUE(
      GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
  ASSERT_EQ(1U, new_sync_profiles.size());
  // Check that key fields are the same.
  EXPECT_TRUE(new_sync_profiles[0].IsSubsetOf(expected_profile, "en-US"));
  // Make sure the additional information of the native profile was saved into
  // the sync profile.
  EXPECT_EQ(ASCIIToUTF16("Fox"),
            new_sync_profiles[0].GetRawInfo(ServerFieldType::COMPANY_NAME));
  // Check that the latest use date is saved.
  EXPECT_EQ(base::Time::FromTimeT(4321), new_sync_profiles[0].use_date());
  // Check that the use counts were added (default value is 1).
  EXPECT_EQ(1U, new_sync_profiles[0].use_count());
}

// Tests that a sync with a new native profile that differ only by name a new
// sync profile results in keeping both profiles.
TEST_F(ProfileSyncServiceAutofillTest, HasNativeHasSync_DifferentPrimaryInfo) {
  AutofillProfile sync_profile;
  autofill::test::SetProfileInfoWithGuid(
      &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
      "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.",
      "unit 5", "Hollywood", "CA", "91601", "US", "12345678910");
  sync_profile.set_use_date(base::Time::FromTimeT(4321));

  std::unique_ptr<AutofillProfile> native_profile =
      std::make_unique<AutofillProfile>();
  autofill::test::SetProfileInfoWithGuid(
      native_profile.get(), "23355099-1170-4B71-8ED4-144470CC9EBF", "Billing",
      "John", "Smith", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
      "Hollywood", "CA", "91601", "US", "12345678910");
  native_profile->set_use_date(base::Time::FromTimeT(1234));

  std::vector<std::unique_ptr<AutofillProfile>> native_profiles;
  native_profiles.push_back(std::move(native_profile));
  auto profile_returner = [&native_profiles]() {
    return std::move(native_profiles);
  };
  EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
      .WillOnce(DoAll(LoadAutofillProfiles(profile_returner), Return(true)));
  EXPECT_CALL(autofill_table(), AddAutofillProfile(MatchProfiles(sync_profile)))
      .WillOnce(Return(true));
  std::vector<AutofillProfile> sync_profiles;
  sync_profiles.push_back(sync_profile);
  AddAutofillProfileHelper add_autofill(this, sync_profiles);

  EXPECT_CALL(personal_data_manager(), Refresh());
  // Adds all entries in |sync_profiles| to sync.
  StartAutofillProfileSyncService(add_autofill.callback());
  ASSERT_TRUE(add_autofill.success());

  std::vector<AutofillProfile> new_sync_profiles;
  ASSERT_TRUE(
      GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
  // The two profiles should be kept.
  ASSERT_EQ(2U, new_sync_profiles.size());
}

// Tests that a new native profile that is the same as a new sync profile except
// with different GUIDs results in the native profile being deleted and replaced
// by the sync profile.
TEST_F(ProfileSyncServiceAutofillTest, MergeProfileWithDifferentGuid) {
  AutofillProfile sync_profile;

  autofill::test::SetProfileInfoWithGuid(
      &sync_profile, "23355099-1170-4B71-8ED4-144470CC9EBE", "Billing",
      "Mitchell", "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.",
      "unit 5", "Hollywood", "CA", "91601", "US", "12345678910");
  sync_profile.set_use_count(20);
  sync_profile.set_use_date(base::Time::FromTimeT(1234));

  std::string native_guid = "EDC609ED-7EEE-4F27-B00C-423242A9C44B";
  std::unique_ptr<AutofillProfile> native_profile =
      std::make_unique<AutofillProfile>();
  autofill::test::SetProfileInfoWithGuid(
      native_profile.get(), native_guid.c_str(), "Billing", "Mitchell",
      "Morrison", "johnwayne@me.xyz", "Fox", "123 Zoo St.", "unit 5",
      "Hollywood", "CA", "91601", "US", "12345678910");
  native_profile->set_use_count(5);
  native_profile->set_use_date(base::Time::FromTimeT(4321));

  std::vector<std::unique_ptr<AutofillProfile>> native_profiles;
  native_profiles.push_back(std::move(native_profile));
  auto profile_returner = [&native_profiles]() {
    return std::move(native_profiles);
  };
  EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
      .WillOnce(DoAll(LoadAutofillProfiles(profile_returner), Return(true)));

  std::vector<AutofillProfile> sync_profiles;
  sync_profiles.push_back(sync_profile);
  AddAutofillProfileHelper add_autofill(this, sync_profiles);

  EXPECT_CALL(autofill_table(), AddAutofillProfile(_)).WillOnce(Return(true));
  EXPECT_CALL(autofill_table(), RemoveAutofillProfile(native_guid))
      .WillOnce(Return(true));
  EXPECT_CALL(personal_data_manager(), Refresh());
  StartAutofillProfileSyncService(add_autofill.callback());
  ASSERT_TRUE(add_autofill.success());

  std::vector<AutofillProfile> new_sync_profiles;
  ASSERT_TRUE(
      GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
  // Check that the profiles were merged.
  ASSERT_EQ(1U, new_sync_profiles.size());
  EXPECT_EQ(0, sync_profile.Compare(new_sync_profiles[0]));
  // Check that the sync guid was kept.
  EXPECT_EQ(sync_profile.guid(), new_sync_profiles[0].guid());
  // Check that the sync profile use count was kept.
  EXPECT_EQ(20U, new_sync_profiles[0].use_count());
  // Check that the sync profile use date was kept.
  EXPECT_EQ(base::Time::FromTimeT(1234), new_sync_profiles[0].use_date());
}

TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeAddProfile) {
  EXPECT_CALL(autofill_table(), GetAutofillProfiles(_)).WillOnce(Return(true));
  EXPECT_CALL(personal_data_manager(), Refresh());
  SetIdleChangeProcessorExpectations();
  CreateRootHelper create_root(this, AUTOFILL_PROFILE);
  StartAutofillProfileSyncService(create_root.callback());
  ASSERT_TRUE(create_root.success());

  AutofillProfile added_profile;
  autofill::test::SetProfileInfoWithGuid(
      &added_profile, "D6ADA912-D374-4C0A-917D-F5C8EBE43011", "Josephine",
      "Alicia", "Saenz", "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
      "Orlando", "FL", "32801", "US", "19482937549");

  // TODO(crbug.com/904390): Remove when the investigation is over. This call is
  // needed in the AutofillProfileChanged() callback.
  EXPECT_CALL(autofill_table(), GetServerProfiles(_)).WillOnce(Return(true));

  AutofillProfileChange change(AutofillProfileChange::ADD, added_profile.guid(),
                               &added_profile);
  web_data_service()->OnAutofillProfileChanged(change);

  std::vector<AutofillProfile> new_sync_profiles;
  ASSERT_TRUE(
      GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
  ASSERT_EQ(1U, new_sync_profiles.size());
  EXPECT_EQ(0, added_profile.Compare(new_sync_profiles[0]));
}

TEST_F(ProfileSyncServiceAutofillTest, ProcessUserChangeRemoveProfile) {
  AutofillProfile sync_profile;
  autofill::test::SetProfileInfoWithGuid(
      &sync_profile, "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine",
      "Alicia", "Saenz", "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
      "Orlando", "FL", "32801", "US", "19482937549");
  std::unique_ptr<AutofillProfile> native_profile =
      std::make_unique<AutofillProfile>();
  autofill::test::SetProfileInfoWithGuid(
      native_profile.get(), "3BA5FA1B-1EC4-4BB3-9B57-EC92BE3C1A09", "Josephine",
      "Alicia", "Saenz", "joewayne@me.xyz", "Fox", "1212 Center.", "Bld. 5",
      "Orlando", "FL", "32801", "US", "19482937549");

  std::vector<std::unique_ptr<AutofillProfile>> native_profiles;
  native_profiles.push_back(std::move(native_profile));
  auto profile_returner = [&native_profiles]() {
    return std::move(native_profiles);
  };
  EXPECT_CALL(autofill_table(), GetAutofillProfiles(_))
      .WillOnce(DoAll(LoadAutofillProfiles(profile_returner), Return(true)));

  std::vector<AutofillProfile> sync_profiles;
  sync_profiles.push_back(sync_profile);
  AddAutofillProfileHelper add_autofill(this, sync_profiles);
  EXPECT_CALL(personal_data_manager(), Refresh());
  StartAutofillProfileSyncService(add_autofill.callback());
  ASSERT_TRUE(add_autofill.success());

  // TODO(crbug.com/904390): Remove when the investigation is over. This call is
  // needed in the AutofillProfileChanged() callback.
  EXPECT_CALL(autofill_table(), GetServerProfiles(_)).WillOnce(Return(true));

  AutofillProfileChange change(AutofillProfileChange::REMOVE,
                               sync_profile.guid(), nullptr);
  web_data_service()->OnAutofillProfileChanged(change);

  std::vector<AutofillProfile> new_sync_profiles;
  ASSERT_TRUE(
      GetAutofillProfilesFromSyncDBUnderProfileNode(&new_sync_profiles));
  ASSERT_EQ(0U, new_sync_profiles.size());
}

}  // namespace browser_sync
