// Copyright 2016 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 "components/autofill/core/browser/webdata/autocomplete_sync_bridge.h"

#include <algorithm>
#include <map>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/autofill/core/browser/webdata/autofill_entry.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/autofill/core/browser/webdata/mock_autofill_webdata_backend.h"
#include "components/sync/base/hash_util.h"
#include "components/sync/model/data_batch.h"
#include "components/sync/model/data_type_activation_request.h"
#include "components/sync/model/metadata_batch.h"
#include "components/sync/model/mock_model_type_change_processor.h"
#include "components/sync/model/model_error.h"
#include "components/sync/model_impl/client_tag_based_model_type_processor.h"
#include "components/sync/test/test_matchers.h"
#include "components/webdata/common/web_database.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::ScopedTempDir;
using base::Time;
using base::TimeDelta;
using base::UTF8ToUTF16;
using sync_pb::AutofillSpecifics;
using sync_pb::EntityMetadata;
using sync_pb::EntitySpecifics;
using sync_pb::ModelTypeState;
using syncer::DataBatch;
using syncer::EntityChange;
using syncer::EntityChangeList;
using syncer::EntityData;
using syncer::EntityDataPtr;
using syncer::HasInitialSyncDone;
using syncer::IsEmptyMetadataBatch;
using syncer::KeyAndData;
using syncer::MockModelTypeChangeProcessor;
using syncer::ModelError;
using syncer::ModelType;
using syncer::ModelTypeChangeProcessor;
using syncer::ModelTypeSyncBridge;
using testing::_;
using testing::IsEmpty;
using testing::Not;
using testing::Return;
using testing::SizeIs;

namespace autofill {

namespace {

const char kNameFormat[] = "name %d";
const char kValueFormat[] = "value %d";

MATCHER_P(HasSpecifics, expected, "") {
  const AutofillSpecifics& s1 = arg->specifics.autofill();
  const AutofillSpecifics& s2 = expected;

  if (s1.usage_timestamp().size() != s2.usage_timestamp().size()) {
    *result_listener << "usage_timstamp().size() not equal: "
                     << s1.usage_timestamp().size()
                     << "!=" << s2.usage_timestamp().size();
    return false;
  }
  int size = std::min(s1.usage_timestamp().size(), s2.usage_timestamp().size());
  for (int i = 0; i < size; ++i) {
    if (s1.usage_timestamp(i) != s2.usage_timestamp(i)) {
      *result_listener << "usage_timstamp(" << i
                       << ") not equal: " << s1.usage_timestamp(i)
                       << "!=" << s2.usage_timestamp(i);
      return false;
    }
  }

  if (s1.name() != s2.name()) {
    *result_listener << "name() not equal: " << s1.name() << "!=" << s2.name();
    return false;
  }

  if (s1.value() != s2.value()) {
    *result_listener << "value() not equal: " << s1.value()
                     << "!=" << s2.value();
    return false;
  }

  if (s1.has_profile() != s2.has_profile()) {
    *result_listener << "has_profile() not equal: " << s1.has_profile()
                     << "!=" << s2.has_profile();
    return false;
  }

  return true;
}

void VerifyDataBatch(std::map<std::string, AutofillSpecifics> expected,
                     std::unique_ptr<DataBatch> batch) {
  while (batch->HasNext()) {
    const KeyAndData& data_pair = batch->Next();
    auto expected_iter = expected.find(data_pair.first);
    ASSERT_NE(expected_iter, expected.end());
    EXPECT_THAT(data_pair.second, HasSpecifics(expected_iter->second));
    // Removing allows us to verify we don't see the same item multiple times,
    // and that we saw everything we expected.
    expected.erase(expected_iter);
  }
  EXPECT_TRUE(expected.empty());
}

AutofillEntry CreateAutofillEntry(const AutofillSpecifics& autofill_specifics) {
  AutofillKey key(UTF8ToUTF16(autofill_specifics.name()),
                  UTF8ToUTF16(autofill_specifics.value()));
  Time date_created, date_last_used;
  const google::protobuf::RepeatedField<int64_t>& timestamps =
      autofill_specifics.usage_timestamp();
  if (!timestamps.empty()) {
    date_created = Time::FromInternalValue(*timestamps.begin());
    date_last_used = Time::FromInternalValue(*timestamps.rbegin());
  }
  return AutofillEntry(key, date_created, date_last_used);
}

}  // namespace

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

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    db_.AddTable(&table_);
    db_.Init(temp_dir_.GetPath().AppendASCII("SyncTestWebDatabase"));
    ON_CALL(*backend(), GetDatabase()).WillByDefault(Return(&db_));
    ResetProcessor();
    ResetBridge();
  }

  void ResetProcessor() {
    real_processor_ =
        std::make_unique<syncer::ClientTagBasedModelTypeProcessor>(
            syncer::AUTOFILL, /*dump_stack=*/base::DoNothing(),
            /*commit_only=*/false);
    mock_processor_.DelegateCallsByDefaultTo(real_processor_.get());
  }

  void ResetBridge() {
    bridge_.reset(new AutocompleteSyncBridge(
        &backend_, mock_processor_.CreateForwardingProcessor()));
  }

  void StartSyncing(const std::vector<AutofillSpecifics>& remote_data = {}) {
    base::RunLoop loop;
    syncer::DataTypeActivationRequest request;
    request.error_handler = base::DoNothing();
    real_processor_->OnSyncStarting(
        request,
        base::BindLambdaForTesting(
            [&loop](std::unique_ptr<syncer::DataTypeActivationResponse>) {
              loop.Quit();
            }));
    loop.Run();

    // Initialize the processor with initial_sync_done.
    sync_pb::ModelTypeState state;
    state.set_initial_sync_done(true);
    syncer::UpdateResponseDataList initial_updates;
    for (const AutofillSpecifics& specifics : remote_data) {
      initial_updates.push_back(SpecificsToUpdateResponse(specifics));
    }
    real_processor_->OnUpdateReceived(state, initial_updates);
  }

  void SaveSpecificsToTable(
      const std::vector<AutofillSpecifics>& specifics_list) {
    std::vector<AutofillEntry> new_entries;
    for (const auto& specifics : specifics_list) {
      new_entries.push_back(CreateAutofillEntry(specifics));
    }
    table_.UpdateAutofillEntries(new_entries);
  }

  AutofillSpecifics CreateSpecifics(const std::string& name,
                                    const std::string& value,
                                    const std::vector<int>& timestamps) {
    AutofillSpecifics specifics;
    specifics.set_name(name);
    specifics.set_value(value);
    for (int timestamp : timestamps) {
      specifics.add_usage_timestamp(
          Time::FromTimeT(timestamp).ToInternalValue());
    }
    return specifics;
  }

  AutofillSpecifics CreateSpecifics(int suffix,
                                    const std::vector<int>& timestamps) {
    return CreateSpecifics(base::StringPrintf(kNameFormat, suffix),
                           base::StringPrintf(kValueFormat, suffix),
                           timestamps);
  }

  AutofillSpecifics CreateSpecifics(int suffix) {
    return CreateSpecifics(suffix, std::vector<int>{0});
  }

  std::string GetClientTag(const AutofillSpecifics& specifics) {
    std::string tag =
        bridge()->GetClientTag(SpecificsToEntity(specifics).value());
    EXPECT_FALSE(tag.empty());
    return tag;
  }

  std::string GetStorageKey(const AutofillSpecifics& specifics) {
    std::string key =
        bridge()->GetStorageKey(SpecificsToEntity(specifics).value());
    EXPECT_FALSE(key.empty());
    return key;
  }

  EntityChangeList CreateEntityAddList(
      const std::vector<AutofillSpecifics>& specifics_vector) {
    EntityChangeList changes;
    for (const auto& specifics : specifics_vector) {
      changes.push_back(EntityChange::CreateAdd(GetStorageKey(specifics),
                                                SpecificsToEntity(specifics)));
    }
    return changes;
  }

  EntityDataPtr SpecificsToEntity(const AutofillSpecifics& specifics) {
    EntityData data;
    *data.specifics.mutable_autofill() = specifics;
    data.client_tag_hash = syncer::GenerateSyncableHash(
        syncer::AUTOFILL, bridge()->GetClientTag(data));
    return data.PassToPtr();
  }

  syncer::UpdateResponseData SpecificsToUpdateResponse(
      const AutofillSpecifics& specifics) {
    syncer::UpdateResponseData data;
    data.entity = SpecificsToEntity(specifics);
    return data;
  }

  void ApplyChanges(const EntityChangeList& changes) {
    const auto error = bridge()->ApplySyncChanges(
        bridge()->CreateMetadataChangeList(), changes);
    EXPECT_FALSE(error);
  }

  void ApplyAdds(const std::vector<AutofillSpecifics>& specifics) {
    ApplyChanges(CreateEntityAddList(specifics));
  }

  std::map<std::string, AutofillSpecifics> ExpectedMap(
      const std::vector<AutofillSpecifics>& specifics_vector) {
    std::map<std::string, AutofillSpecifics> map;
    for (const auto& specifics : specifics_vector) {
      map[GetStorageKey(specifics)] = specifics;
    }
    return map;
  }

  void VerifyAllData(const std::vector<AutofillSpecifics>& expected) {
    bridge()->GetAllDataForDebugging(
        base::BindOnce(&VerifyDataBatch, ExpectedMap(expected)));
  }

  AutocompleteSyncBridge* bridge() { return bridge_.get(); }

  syncer::MockModelTypeChangeProcessor& mock_processor() {
    return mock_processor_;
  }

  AutofillTable* table() { return &table_; }

  MockAutofillWebDataBackend* backend() { return &backend_; }

 private:
  ScopedTempDir temp_dir_;
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  testing::NiceMock<MockAutofillWebDataBackend> backend_;
  AutofillTable table_;
  WebDatabase db_;
  std::unique_ptr<AutocompleteSyncBridge> bridge_;
  testing::NiceMock<MockModelTypeChangeProcessor> mock_processor_;
  std::unique_ptr<syncer::ClientTagBasedModelTypeProcessor> real_processor_;

  DISALLOW_COPY_AND_ASSIGN(AutocompleteSyncBridgeTest);
};

TEST_F(AutocompleteSyncBridgeTest, GetClientTag) {
  std::string tag = GetClientTag(CreateSpecifics(1));
  EXPECT_EQ(tag, GetClientTag(CreateSpecifics(1)));
  EXPECT_NE(tag, GetClientTag(CreateSpecifics(2)));
}

TEST_F(AutocompleteSyncBridgeTest, GetClientTagNotAffectedByTimestamp) {
  AutofillSpecifics specifics = CreateSpecifics(1);
  std::string tag = GetClientTag(specifics);

  specifics.add_usage_timestamp(1);
  EXPECT_EQ(tag, GetClientTag(specifics));

  specifics.add_usage_timestamp(0);
  EXPECT_EQ(tag, GetClientTag(specifics));

  specifics.add_usage_timestamp(-1);
  EXPECT_EQ(tag, GetClientTag(specifics));
}

TEST_F(AutocompleteSyncBridgeTest, GetClientTagRespectsNullCharacter) {
  AutofillSpecifics specifics;
  std::string tag = GetClientTag(specifics);

  specifics.set_value(std::string("\0", 1));
  EXPECT_NE(tag, GetClientTag(specifics));
}

// The client tags should never change as long as we want to maintain backwards
// compatibility with the previous iteration of autocomplete-sync integration,
// AutocompleteSyncableService and Sync's Directory. This is because old clients
// will re-generate client tags and then hashes on local changes, and this
// process must create identical values to what this client has created. If this
// test case starts failing, you should not alter the fixed values here unless
// you know what you're doing.
TEST_F(AutocompleteSyncBridgeTest, GetClientTagFixed) {
  EXPECT_EQ("autofill_entry|name%201|value%201",
            GetClientTag(CreateSpecifics(1)));
  EXPECT_EQ("autofill_entry|name%202|value%202",
            GetClientTag(CreateSpecifics(2)));
  EXPECT_EQ("autofill_entry||", GetClientTag(AutofillSpecifics()));
  AutofillSpecifics specifics;
  specifics.set_name("\xEC\xA4\x91");
  specifics.set_value("\xD0\x80");
  EXPECT_EQ("autofill_entry|%EC%A4%91|%D0%80", GetClientTag(specifics));
}

TEST_F(AutocompleteSyncBridgeTest, GetStorageKey) {
  std::string key = GetStorageKey(CreateSpecifics(1));
  EXPECT_EQ(key, GetStorageKey(CreateSpecifics(1)));
  EXPECT_NE(key, GetStorageKey(CreateSpecifics(2)));
}

TEST_F(AutocompleteSyncBridgeTest, GetStorageKeyNotAffectedByTimestamp) {
  AutofillSpecifics specifics = CreateSpecifics(1);
  std::string key = GetStorageKey(specifics);

  specifics.add_usage_timestamp(1);
  EXPECT_EQ(key, GetStorageKey(specifics));

  specifics.add_usage_timestamp(0);
  EXPECT_EQ(key, GetStorageKey(specifics));

  specifics.add_usage_timestamp(-1);
  EXPECT_EQ(key, GetStorageKey(specifics));
}

TEST_F(AutocompleteSyncBridgeTest, GetStorageKeyRespectsNullCharacter) {
  AutofillSpecifics specifics;
  std::string key = GetStorageKey(specifics);

  specifics.set_value(std::string("\0", 1));
  EXPECT_NE(key, GetStorageKey(specifics));
}

// The storage key should never accidentally change for existing data. This
// would cause lookups to fail and either lose or duplicate user data. It should
// be possible for the model type to migrate storage key formats, but doing so
// would need to be done very carefully.
TEST_F(AutocompleteSyncBridgeTest, GetStorageKeyFixed) {
  EXPECT_EQ("\n\x6name 1\x12\avalue 1", GetStorageKey(CreateSpecifics(1)));
  EXPECT_EQ("\n\x6name 2\x12\avalue 2", GetStorageKey(CreateSpecifics(2)));
  // This literal contains the null terminating character, which causes
  // std::string to stop copying early if we don't tell it how much to read.
  EXPECT_EQ(std::string("\n\0\x12\0", 4), GetStorageKey(AutofillSpecifics()));
  AutofillSpecifics specifics;
  specifics.set_name("\xEC\xA4\x91");
  specifics.set_value("\xD0\x80");
  EXPECT_EQ("\n\x3\xEC\xA4\x91\x12\x2\xD0\x80", GetStorageKey(specifics));
}

TEST_F(AutocompleteSyncBridgeTest, GetData) {
  const AutofillSpecifics specifics1 = CreateSpecifics(1);
  const AutofillSpecifics specifics2 = CreateSpecifics(2);
  const AutofillSpecifics specifics3 = CreateSpecifics(3);
  SaveSpecificsToTable({specifics1, specifics2, specifics3});
  bridge()->GetData(
      {GetStorageKey(specifics1), GetStorageKey(specifics3)},
      base::BindOnce(&VerifyDataBatch, ExpectedMap({specifics1, specifics3})));
}

TEST_F(AutocompleteSyncBridgeTest, GetDataNotExist) {
  const AutofillSpecifics specifics1 = CreateSpecifics(1);
  const AutofillSpecifics specifics2 = CreateSpecifics(2);
  const AutofillSpecifics specifics3 = CreateSpecifics(3);
  SaveSpecificsToTable({specifics1, specifics2});
  bridge()->GetData(
      {GetStorageKey(specifics1), GetStorageKey(specifics2),
       GetStorageKey(specifics3)},
      base::BindOnce(&VerifyDataBatch, ExpectedMap({specifics1, specifics2})));
}

TEST_F(AutocompleteSyncBridgeTest, GetAllData) {
  const AutofillSpecifics specifics1 = CreateSpecifics(1);
  const AutofillSpecifics specifics2 = CreateSpecifics(2);
  const AutofillSpecifics specifics3 = CreateSpecifics(3);
  SaveSpecificsToTable({specifics1, specifics2, specifics3});
  VerifyAllData({specifics1, specifics2, specifics3});
}

TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesEmpty) {
  // TODO(skym, crbug.com/672619): Ideally would like to verify that the db is
  // not accessed.
  ApplyAdds(std::vector<AutofillSpecifics>());
}

TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesSimple) {
  AutofillSpecifics specifics1 = CreateSpecifics(1);
  AutofillSpecifics specifics2 = CreateSpecifics(2);
  ASSERT_NE(specifics1.SerializeAsString(), specifics2.SerializeAsString());
  ASSERT_NE(GetStorageKey(specifics1), GetStorageKey(specifics2));

  ApplyAdds({specifics1, specifics2});
  VerifyAllData({specifics1, specifics2});

  ApplyChanges({EntityChange::CreateDelete(GetStorageKey(specifics1))});
  VerifyAllData({specifics2});
}

// Should be resilient to deleting and updating non-existent things, and adding
// existing ones.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesWrongChangeType) {
  AutofillSpecifics specifics = CreateSpecifics(1, {1});
  ApplyChanges({EntityChange::CreateDelete(GetStorageKey(specifics))});
  VerifyAllData(std::vector<AutofillSpecifics>());

  ApplyChanges({EntityChange::CreateUpdate(GetStorageKey(specifics),
                                           SpecificsToEntity(specifics))});
  VerifyAllData({specifics});

  specifics.add_usage_timestamp(Time::FromTimeT(2).ToInternalValue());
  ApplyAdds({specifics});
  VerifyAllData({specifics});
}

// The format in the table has a fixed 2 timestamp format. Round tripping is
// lossy and the middle value should be thrown out.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesThreeTimestamps) {
  ApplyAdds({CreateSpecifics(1, {1, 2, 3})});
  VerifyAllData({CreateSpecifics(1, {1, 3})});
}

// The correct format of timestamps is that the first should be smaller and the
// second should be larger. Bad foreign data should be repaired.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesWrongOrder) {
  ApplyAdds({CreateSpecifics(1, {3, 2})});
  VerifyAllData({CreateSpecifics(1, {2, 3})});
}

// In a minor attempt to save bandwidth, we only send one of the two timestamps
// when they share a value.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesRepeatedTime) {
  ApplyAdds({CreateSpecifics(1, {2, 2})});
  VerifyAllData({CreateSpecifics(1, {2})});
}

// Again, the format in the table is lossy, and cannot distinguish between no
// time, and valid time zero.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesNoTime) {
  ApplyAdds({CreateSpecifics(1, std::vector<int>())});
  VerifyAllData({CreateSpecifics(1, {0})});
}

// If has_value() returns false, then the specifics are determined to be old
// style and ignored.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesNoValue) {
  AutofillSpecifics input = CreateSpecifics(1, {2, 3});
  input.clear_value();
  ApplyAdds({input});
  VerifyAllData(std::vector<AutofillSpecifics>());
}

// Should be treated the same as an empty string name. This inconsistency is
// being perpetuated from the previous sync integration.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesNoName) {
  AutofillSpecifics input = CreateSpecifics(1, {2, 3});
  input.clear_name();
  ApplyAdds({input});
  VerifyAllData({input});
}

// UTF-8 characters should not be dropped when round tripping, including middle
// of string \0 characters.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesUTF) {
  const AutofillSpecifics specifics =
      CreateSpecifics(std::string("\n\0\x12\0", 4), "\xEC\xA4\x91", {1});
  ApplyAdds({specifics});
  VerifyAllData({specifics});
}

// Timestamps should always use the oldest creation time, and the most recent
// usage time.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesMinMaxTimestamps) {
  const AutofillSpecifics initial = CreateSpecifics(1, {3, 6});
  ApplyAdds({initial});
  VerifyAllData({initial});

  ApplyAdds({CreateSpecifics(1, {2, 5})});
  VerifyAllData({CreateSpecifics(1, {2, 6})});

  ApplyAdds({CreateSpecifics(1, {4, 7})});
  VerifyAllData({CreateSpecifics(1, {2, 7})});
}

// An error should be generated when parsing the storage key happens. This
// should never happen in practice because storage keys should be generated at
// runtime by the bridge and not loaded from disk.
TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesBadStorageKey) {
  const auto error = bridge()->ApplySyncChanges(
      bridge()->CreateMetadataChangeList(),
      {EntityChange::CreateDelete("bogus storage key")});
  EXPECT_TRUE(error);
}

TEST_F(AutocompleteSyncBridgeTest, ApplySyncChangesDatabaseFailure) {
  // TODO(skym, crbug.com/672619): Should have tests that get false back when
  // making db calls and verify the errors are propagated up.
}

TEST_F(AutocompleteSyncBridgeTest, LocalEntriesAdded) {
  StartSyncing();
  const AutofillSpecifics added_specifics1 = CreateSpecifics(1, {2, 3});
  const AutofillSpecifics added_specifics2 = CreateSpecifics(2, {2, 3});

  const AutofillEntry added_entry1 = CreateAutofillEntry(added_specifics1);
  const AutofillEntry added_entry2 = CreateAutofillEntry(added_specifics2);

  table()->UpdateAutofillEntries({added_entry1, added_entry2});

  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(added_specifics1), _));
  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(added_specifics2), _));
  bridge()->AutofillEntriesChanged(
      {AutofillChange(AutofillChange::ADD, added_entry1.key()),
       AutofillChange(AutofillChange::ADD, added_entry2.key())});
}

TEST_F(AutocompleteSyncBridgeTest, LocalEntryAddedThenUpdated) {
  StartSyncing();
  const AutofillSpecifics added_specifics = CreateSpecifics(1, {2, 3});
  const AutofillEntry added_entry = CreateAutofillEntry(added_specifics);
  table()->UpdateAutofillEntries({added_entry});
  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(added_specifics), _));

  bridge()->AutofillEntriesChanged(
      {AutofillChange(AutofillChange::ADD, added_entry.key())});

  const AutofillSpecifics updated_specifics = CreateSpecifics(1, {2, 4});
  const AutofillEntry updated_entry = CreateAutofillEntry(updated_specifics);
  table()->UpdateAutofillEntries({updated_entry});
  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(updated_specifics), _));

  bridge()->AutofillEntriesChanged(
      {AutofillChange(AutofillChange::UPDATE, updated_entry.key())});
}

TEST_F(AutocompleteSyncBridgeTest, LocalEntryDeleted) {
  StartSyncing();
  const AutofillSpecifics deleted_specifics = CreateSpecifics(1, {2, 3});
  const AutofillEntry deleted_entry = CreateAutofillEntry(deleted_specifics);
  const std::string storage_key = GetStorageKey(deleted_specifics);

  EXPECT_CALL(mock_processor(), Delete(storage_key, _));
  bridge()->AutofillEntriesChanged(
      {AutofillChange(AutofillChange::REMOVE, deleted_entry.key())});
}

TEST_F(AutocompleteSyncBridgeTest, LoadMetadataCalled) {
  ModelTypeState model_type_state;
  model_type_state.set_initial_sync_done(true);
  EXPECT_TRUE(
      table()->UpdateModelTypeState(syncer::AUTOFILL, model_type_state));
  EXPECT_TRUE(
      table()->UpdateSyncMetadata(syncer::AUTOFILL, "key", EntityMetadata()));

  ResetProcessor();
  EXPECT_CALL(mock_processor(), ModelReadyToSync(MetadataBatchContains(
                                    /*state=*/HasInitialSyncDone(),
                                    /*entities=*/SizeIs(1))));
  ResetBridge();
}

TEST_F(AutocompleteSyncBridgeTest, LoadMetadataReportsErrorForMissingDB) {
  ON_CALL(*backend(), GetDatabase()).WillByDefault(Return(nullptr));
  EXPECT_CALL(mock_processor(), ReportError(_));
  ResetBridge();
}

TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataEmpty) {
  EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
  EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);

  StartSyncing(/*remote_data=*/std::vector<AutofillSpecifics>());

  VerifyAllData(std::vector<AutofillSpecifics>());
}

TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataRemoteOnly) {
  const AutofillSpecifics specifics1 = CreateSpecifics(1, {2});
  const AutofillSpecifics specifics2 = CreateSpecifics(2, {3, 4});

  EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);
  EXPECT_CALL(mock_processor(), Put(_, _, _)).Times(0);

  StartSyncing(/*remote_data=*/{specifics1, specifics2});

  VerifyAllData({specifics1, specifics2});
}

TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataLocalOnly) {
  const AutofillSpecifics specifics1 = CreateSpecifics(1, {2});
  const AutofillSpecifics specifics2 = CreateSpecifics(2, {3, 4});

  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(specifics1), _));
  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(specifics2), _));
  EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);

  ApplyAdds({specifics1, specifics2});
  VerifyAllData({specifics1, specifics2});

  StartSyncing(/*remote_data=*/{});
  VerifyAllData({specifics1, specifics2});
}

TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataAllMerged) {
  const AutofillSpecifics local1 = CreateSpecifics(1, {2});
  const AutofillSpecifics local2 = CreateSpecifics(2, {3, 4});
  const AutofillSpecifics local3 = CreateSpecifics(3, {4});
  const AutofillSpecifics local4 = CreateSpecifics(4, {5, 6});
  const AutofillSpecifics local5 = CreateSpecifics(5, {6, 9});
  const AutofillSpecifics local6 = CreateSpecifics(6, {7, 9});
  const AutofillSpecifics remote1 = local1;
  const AutofillSpecifics remote2 = local2;
  const AutofillSpecifics remote3 = CreateSpecifics(3, {5});
  const AutofillSpecifics remote4 = CreateSpecifics(4, {7, 8});
  const AutofillSpecifics remote5 = CreateSpecifics(5, {8, 9});
  const AutofillSpecifics remote6 = CreateSpecifics(6, {8, 10});
  const AutofillSpecifics merged1 = local1;
  const AutofillSpecifics merged2 = local2;
  const AutofillSpecifics merged3 = CreateSpecifics(3, {4, 5});
  const AutofillSpecifics merged4 = CreateSpecifics(4, {5, 8});
  const AutofillSpecifics merged5 = local5;
  const AutofillSpecifics merged6 = CreateSpecifics(6, {7, 10});

  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(merged3), _));
  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(merged4), _));
  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(merged5), _));
  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(merged6), _));
  EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);

  ApplyAdds({local1, local2, local3, local4, local5, local6});

  StartSyncing(
      /*remote_data=*/{remote1, remote2, remote3, remote4, remote5, remote6});
  VerifyAllData({merged1, merged2, merged3, merged4, merged5, merged6});
}

TEST_F(AutocompleteSyncBridgeTest, MergeSyncDataMixed) {
  const AutofillSpecifics local1 = CreateSpecifics(1, {2, 3});
  const AutofillSpecifics remote2 = CreateSpecifics(2, {2, 3});
  const AutofillSpecifics specifics3 = CreateSpecifics(3, {2, 3});
  const AutofillSpecifics local4 = CreateSpecifics(4, {1, 3});
  const AutofillSpecifics remote4 = CreateSpecifics(4, {2, 4});
  const AutofillSpecifics merged4 = CreateSpecifics(4, {1, 4});

  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(local1), _));
  EXPECT_CALL(mock_processor(), Put(_, HasSpecifics(merged4), _));
  EXPECT_CALL(mock_processor(), Delete(_, _)).Times(0);

  ApplyAdds({local1, specifics3, local4});

  StartSyncing(/*remote_data=*/{remote2, specifics3, remote4});

  VerifyAllData({local1, remote2, specifics3, merged4});
}

}  // namespace autofill
