// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/sync/engine/commit_contribution_impl.h"

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

#include "base/base64.h"
#include "base/functional/callback_helpers.h"
#include "base/hash/sha1.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
#include "components/sync/base/client_tag_hash.h"
#include "components/sync/base/features.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/unique_position.h"
#include "components/sync/engine/nigori/cryptographer.h"
#include "components/sync/protocol/data_type_progress_marker.pb.h"
#include "components/sync/protocol/entity_specifics.pb.h"
#include "components/sync/protocol/password_specifics.pb.h"
#include "components/sync/protocol/sharing_message_specifics.pb.h"
#include "components/sync/protocol/sync.pb.h"
#include "components/sync/protocol/sync_entity.pb.h"
#include "components/sync/test/fake_cryptographer.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace syncer {

namespace {

using sync_pb::CommitResponse;
using sync_pb::EntitySpecifics;
using sync_pb::SharingMessageCommitError;
using sync_pb::SyncEntity;

const ClientTagHash kTag = ClientTagHash::FromHashed("tag");
const char kValue[] = "value";
const char kURL[] = "url";
const char kTitle[] = "title";

EntitySpecifics GeneratePreferenceSpecifics(const ClientTagHash& tag,
                                            const std::string& value) {
  EntitySpecifics specifics;
  specifics.mutable_preference()->set_name(tag.value());
  specifics.mutable_preference()->set_value(value);
  return specifics;
}

EntitySpecifics GenerateBookmarkSpecifics(const std::string& url,
                                          const std::string& title) {
  EntitySpecifics specifics;
  specifics.mutable_bookmark()->set_legacy_canonicalized_title(title);
  if (url.empty()) {
    specifics.mutable_bookmark()->set_type(sync_pb::BookmarkSpecifics::FOLDER);
  } else {
    specifics.mutable_bookmark()->set_type(sync_pb::BookmarkSpecifics::URL);
    specifics.mutable_bookmark()->set_url(url);
  }
  *specifics.mutable_bookmark()->mutable_unique_position() =
      syncer::UniquePosition::FromInt64(10,
                                        syncer::UniquePosition::RandomSuffix())
          .ToProto();
  return specifics;
}

TEST(CommitContributionImplTest, PopulateCommitProtoDefault) {
  const int64_t kBaseVersion = 7;
  base::Time creation_time = base::Time::UnixEpoch() + base::Days(1);
  base::Time modification_time = creation_time + base::Seconds(1);

  auto data = std::make_unique<syncer::EntityData>();

  data->client_tag_hash = kTag;
  data->specifics = GeneratePreferenceSpecifics(kTag, kValue);

  // These fields are not really used for much, but we set them anyway
  // to make this item look more realistic.
  data->creation_time = creation_time;
  data->modification_time = modification_time;
  data->name = "Name:";

  CommitRequestData request_data;
  request_data.sequence_number = 2;
  request_data.base_version = kBaseVersion;
  base::Base64Encode(base::SHA1HashString(data->specifics.SerializeAsString()),
                     &request_data.specifics_hash);
  request_data.entity = std::move(data);

  SyncEntity entity;
  CommitContributionImpl::PopulateCommitProto(PREFERENCES, request_data,
                                              &entity);

  // Exhaustively verify the populated SyncEntity.
  EXPECT_TRUE(entity.id_string().empty());
  EXPECT_EQ(7, entity.version());
  EXPECT_EQ(modification_time.ToJsTime(), entity.mtime());
  EXPECT_EQ(creation_time.ToJsTime(), entity.ctime());
  EXPECT_FALSE(entity.name().empty());
  EXPECT_FALSE(entity.client_tag_hash().empty());
  EXPECT_EQ(kTag.value(), entity.specifics().preference().name());
  EXPECT_FALSE(entity.deleted());
  EXPECT_EQ(kValue, entity.specifics().preference().value());
  EXPECT_TRUE(entity.parent_id_string().empty());
  EXPECT_FALSE(entity.unique_position().has_custom_compressed_v1());
}

TEST(CommitContributionImplTest, PopulateCommitProtoBookmark) {
  const int64_t kBaseVersion = 7;
  base::Time creation_time = base::Time::UnixEpoch() + base::Days(1);
  base::Time modification_time = creation_time + base::Seconds(1);

  auto data = std::make_unique<syncer::EntityData>();

  data->id = "bookmark";
  data->specifics = GenerateBookmarkSpecifics(kURL, kTitle);

  // These fields are not really used for much, but we set them anyway
  // to make this item look more realistic.
  data->creation_time = creation_time;
  data->modification_time = modification_time;
  data->name = "Name:";
  data->legacy_parent_id = "ParentOf:";

  CommitRequestData request_data;
  request_data.sequence_number = 2;
  request_data.base_version = kBaseVersion;
  base::Base64Encode(base::SHA1HashString(data->specifics.SerializeAsString()),
                     &request_data.specifics_hash);
  request_data.entity = std::move(data);

  SyncEntity entity;
  CommitContributionImpl::PopulateCommitProto(BOOKMARKS, request_data, &entity);

  // Exhaustively verify the populated SyncEntity.
  EXPECT_FALSE(entity.id_string().empty());
  EXPECT_EQ(7, entity.version());
  EXPECT_EQ(modification_time.ToJsTime(), entity.mtime());
  EXPECT_EQ(creation_time.ToJsTime(), entity.ctime());
  EXPECT_FALSE(entity.name().empty());
  EXPECT_TRUE(entity.client_tag_hash().empty());
  EXPECT_EQ(kURL, entity.specifics().bookmark().url());
  EXPECT_FALSE(entity.deleted());
  EXPECT_EQ(kTitle, entity.specifics().bookmark().legacy_canonicalized_title());
  EXPECT_FALSE(entity.folder());
  EXPECT_FALSE(entity.parent_id_string().empty());
  EXPECT_TRUE(entity.unique_position().has_custom_compressed_v1());
}

TEST(CommitContributionImplTest, PopulateCommitProtoBookmarkFolder) {
  const int64_t kBaseVersion = 7;
  base::Time creation_time = base::Time::UnixEpoch() + base::Days(1);
  base::Time modification_time = creation_time + base::Seconds(1);

  auto data = std::make_unique<syncer::EntityData>();

  data->id = "bookmark";
  data->specifics = GenerateBookmarkSpecifics(/*url=*/"", kTitle);

  // These fields are not really used for much, but we set them anyway
  // to make this item look more realistic.
  data->creation_time = creation_time;
  data->modification_time = modification_time;
  data->name = "Name:";
  data->legacy_parent_id = "ParentOf:";

  CommitRequestData request_data;
  request_data.sequence_number = 2;
  request_data.base_version = kBaseVersion;
  base::Base64Encode(base::SHA1HashString(data->specifics.SerializeAsString()),
                     &request_data.specifics_hash);
  request_data.entity = std::move(data);

  SyncEntity entity;
  CommitContributionImpl::PopulateCommitProto(BOOKMARKS, request_data, &entity);

  // Exhaustively verify the populated SyncEntity.
  EXPECT_FALSE(entity.id_string().empty());
  EXPECT_EQ(7, entity.version());
  EXPECT_EQ(modification_time.ToJsTime(), entity.mtime());
  EXPECT_EQ(creation_time.ToJsTime(), entity.ctime());
  EXPECT_FALSE(entity.name().empty());
  EXPECT_TRUE(entity.client_tag_hash().empty());
  EXPECT_FALSE(entity.specifics().bookmark().has_url());
  EXPECT_FALSE(entity.deleted());
  EXPECT_EQ(kTitle, entity.specifics().bookmark().legacy_canonicalized_title());
  EXPECT_TRUE(entity.folder());
  EXPECT_FALSE(entity.parent_id_string().empty());
  EXPECT_TRUE(entity.unique_position().has_custom_compressed_v1());
}

// Verifies how PASSWORDS protos are committed on the wire, making sure the data
// is properly encrypted except for password metadata.
TEST(CommitContributionImplTest,
     PopulateCommitProtoPasswordWithoutCustomPassphrase) {
  const std::string kSignonRealm = "signon_realm";
  const int64_t kBaseVersion = 7;
  const int kDummyTimestamp = 123;

  auto data = std::make_unique<syncer::EntityData>();
  data->client_tag_hash = kTag;
  sync_pb::PasswordSpecificsData* password_data =
      data->specifics.mutable_password()->mutable_client_only_encrypted_data();
  password_data->set_signon_realm(kSignonRealm);
  password_data->set_date_last_used(kDummyTimestamp);

  data->specifics.mutable_password()->mutable_unencrypted_metadata()->set_url(
      kSignonRealm);
  data->specifics.mutable_password()
      ->mutable_unencrypted_metadata()
      ->set_blacklisted(false);
  data->specifics.mutable_password()
      ->mutable_unencrypted_metadata()
      ->set_date_last_used_windows_epoch_micros(kDummyTimestamp);

  auto request_data = std::make_unique<CommitRequestData>();
  request_data->sequence_number = 2;
  request_data->base_version = kBaseVersion;
  base::Base64Encode(base::SHA1HashString(data->specifics.SerializeAsString()),
                     &request_data->specifics_hash);
  request_data->entity = std::move(data);

  std::unique_ptr<FakeCryptographer> cryptographer =
      FakeCryptographer::FromSingleDefaultKey("dummy");

  CommitRequestDataList requests_data;
  requests_data.push_back(std::move(request_data));
  CommitContributionImpl contribution(
      PASSWORDS, sync_pb::DataTypeContext(), std::move(requests_data),
      /*on_commit_response_callback=*/base::NullCallback(),
      /*on_full_commit_failure_callback=*/base::NullCallback(),
      cryptographer.get(), PassphraseType::kImplicitPassphrase,
      /*only_commit_specifics=*/false);

  sync_pb::ClientToServerMessage msg;
  contribution.AddToCommitMessage(&msg);

  ASSERT_EQ(1, msg.commit().entries().size());
  SyncEntity entity = msg.commit().entries(0);

  // Exhaustively verify the populated SyncEntity.
  EXPECT_TRUE(entity.id_string().empty());
  EXPECT_EQ(7, entity.version());
  EXPECT_EQ("encrypted", entity.name());
  EXPECT_EQ(kTag.value(), entity.client_tag_hash());
  EXPECT_FALSE(entity.deleted());
  EXPECT_FALSE(entity.specifics().has_encrypted());
  EXPECT_TRUE(entity.specifics().has_password());
  EXPECT_EQ(kSignonRealm,
            entity.specifics().password().unencrypted_metadata().url());
  EXPECT_TRUE(
      entity.specifics().password().unencrypted_metadata().has_blacklisted());
  EXPECT_FALSE(
      entity.specifics().password().unencrypted_metadata().blacklisted());
  EXPECT_EQ(kDummyTimestamp, entity.specifics()
                                 .password()
                                 .unencrypted_metadata()
                                 .date_last_used_windows_epoch_micros());
  EXPECT_FALSE(entity.specifics().password().encrypted().blob().empty());
  EXPECT_TRUE(entity.parent_id_string().empty());
  EXPECT_FALSE(entity.unique_position().has_custom_compressed_v1());
}

// Same as above but uses CUSTOM_PASSPHRASE. In this case, field
// |unencrypted_metadata| should be cleared.
TEST(CommitContributionImplTest,
     PopulateCommitProtoPasswordWithCustomPassphrase) {
  const std::string kSignonRealm = "signon_realm";
  const int kDummyTimestamp = 123;
  const int64_t kBaseVersion = 7;

  auto data = std::make_unique<syncer::EntityData>();
  data->client_tag_hash = kTag;
  sync_pb::PasswordSpecificsData* password_data =
      data->specifics.mutable_password()->mutable_client_only_encrypted_data();
  password_data->set_signon_realm(kSignonRealm);

  data->specifics.mutable_password()->mutable_unencrypted_metadata()->set_url(
      kSignonRealm);
  data->specifics.mutable_password()
      ->mutable_unencrypted_metadata()
      ->set_blacklisted(false);
  data->specifics.mutable_password()
      ->mutable_unencrypted_metadata()
      ->set_date_last_used_windows_epoch_micros(kDummyTimestamp);

  auto request_data = std::make_unique<CommitRequestData>();
  request_data->sequence_number = 2;
  request_data->base_version = kBaseVersion;
  base::Base64Encode(base::SHA1HashString(data->specifics.SerializeAsString()),
                     &request_data->specifics_hash);
  request_data->entity = std::move(data);

  std::unique_ptr<FakeCryptographer> cryptographer =
      FakeCryptographer::FromSingleDefaultKey("dummy");

  CommitRequestDataList requests_data;
  requests_data.push_back(std::move(request_data));
  CommitContributionImpl contribution(
      PASSWORDS, sync_pb::DataTypeContext(), std::move(requests_data),
      /*on_commit_response_callback=*/base::NullCallback(),
      /*on_full_commit_failure_callback=*/base::NullCallback(),
      cryptographer.get(), PassphraseType::kCustomPassphrase,
      /*only_commit_specifics=*/false);

  sync_pb::ClientToServerMessage msg;
  contribution.AddToCommitMessage(&msg);

  ASSERT_EQ(1, msg.commit().entries().size());
  SyncEntity entity = msg.commit().entries(0);

  // Exhaustively verify the populated SyncEntity.
  EXPECT_TRUE(entity.id_string().empty());
  EXPECT_EQ(7, entity.version());
  EXPECT_EQ("encrypted", entity.name());
  EXPECT_EQ(kTag.value(), entity.client_tag_hash());
  EXPECT_FALSE(entity.deleted());
  EXPECT_FALSE(entity.specifics().has_encrypted());
  EXPECT_TRUE(entity.specifics().has_password());
  EXPECT_FALSE(entity.specifics().password().encrypted().blob().empty());
  EXPECT_FALSE(entity.specifics().password().has_unencrypted_metadata());
  EXPECT_TRUE(entity.parent_id_string().empty());
  EXPECT_FALSE(entity.unique_position().has_custom_compressed_v1());
}

TEST(CommitContributionImplTest, ShouldPropagateFailedItemsOnCommitResponse) {
  auto data = std::make_unique<syncer::EntityData>();
  data->client_tag_hash = ClientTagHash::FromHashed("hash");
  auto request_data = std::make_unique<CommitRequestData>();
  request_data->entity = std::move(data);
  CommitRequestDataList requests_data;
  requests_data.push_back(std::move(request_data));

  FakeCryptographer cryptographer;

  FailedCommitResponseDataList actual_error_response_list;

  auto on_commit_response_callback = base::BindOnce(
      [](FailedCommitResponseDataList* actual_error_response_list,
         const CommitResponseDataList& committed_response_list,
         const FailedCommitResponseDataList& error_response_list) {
        // We put expectations outside of the callback, so that they fail if
        // callback is not ran.
        *actual_error_response_list = error_response_list;
      },
      &actual_error_response_list);

  CommitContributionImpl contribution(
      PASSWORDS, sync_pb::DataTypeContext(), std::move(requests_data),
      std::move(on_commit_response_callback),
      /*on_full_commit_failure_callback=*/base::NullCallback(), &cryptographer,
      PassphraseType::kCustomPassphrase,
      /*only_commit_specifics=*/false);

  sync_pb::ClientToServerMessage msg;
  contribution.AddToCommitMessage(&msg);

  sync_pb::ClientToServerResponse response;
  sync_pb::CommitResponse* commit_response = response.mutable_commit();

  {
    sync_pb::CommitResponse_EntryResponse* entry =
        commit_response->add_entryresponse();
    entry->set_response_type(CommitResponse::TRANSIENT_ERROR);
    SharingMessageCommitError* sharing_message_error =
        entry->mutable_datatype_specific_error()
            ->mutable_sharing_message_error();
    sharing_message_error->set_error_code(
        SharingMessageCommitError::INVALID_ARGUMENT);
  }

  StatusController status;
  contribution.ProcessCommitResponse(response, &status);

  ASSERT_EQ(1u, actual_error_response_list.size());
  FailedCommitResponseData failed_item = actual_error_response_list[0];
  EXPECT_EQ(ClientTagHash::FromHashed("hash"), failed_item.client_tag_hash);
  EXPECT_EQ(CommitResponse::TRANSIENT_ERROR, failed_item.response_type);
  EXPECT_EQ(
      SharingMessageCommitError::INVALID_ARGUMENT,
      failed_item.datatype_specific_error.sharing_message_error().error_code());
}

TEST(CommitContributionImplTest, ShouldPropagateFullCommitFailure) {
  base::MockOnceCallback<void(SyncCommitError commit_error)>
      on_commit_failure_callback;
  EXPECT_CALL(on_commit_failure_callback, Run(SyncCommitError::kNetworkError));

  CommitContributionImpl contribution(
      BOOKMARKS, sync_pb::DataTypeContext(), CommitRequestDataList(),
      /*on_commit_response_callback=*/base::NullCallback(),
      on_commit_failure_callback.Get(), /*cryptographer=*/nullptr,
      PassphraseType::kKeystorePassphrase,
      /*only_commit_specifics=*/false);

  contribution.ProcessCommitFailure(SyncCommitError::kNetworkError);
}

TEST(CommitContributionImplTest, ShouldPopulatePasswordNotesBackup) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(syncer::kPasswordNotesWithBackup);

  const std::string kNoteValue = "Note Value";
  auto data = std::make_unique<syncer::EntityData>();
  data->client_tag_hash = kTag;
  sync_pb::PasswordSpecificsData* password_data =
      data->specifics.mutable_password()->mutable_client_only_encrypted_data();
  sync_pb::PasswordSpecificsData_Notes_Note* note =
      password_data->mutable_notes()->add_note();
  note->set_value(kNoteValue);

  auto request_data = std::make_unique<CommitRequestData>();
  base::Base64Encode(base::SHA1HashString(data->specifics.SerializeAsString()),
                     &request_data->specifics_hash);
  request_data->entity = std::move(data);

  CommitRequestDataList requests_data;
  requests_data.push_back(std::move(request_data));

  std::unique_ptr<FakeCryptographer> cryptographer =
      FakeCryptographer::FromSingleDefaultKey("dummy");
  CommitContributionImpl contribution(
      PASSWORDS, sync_pb::DataTypeContext(), std::move(requests_data),
      /*on_commit_response_callback=*/base::NullCallback(),
      /*on_full_commit_failure_callback=*/base::NullCallback(),
      cryptographer.get(), PassphraseType::kImplicitPassphrase,
      /*only_commit_specifics=*/false);

  sync_pb::ClientToServerMessage msg;
  contribution.AddToCommitMessage(&msg);

  ASSERT_EQ(1, msg.commit().entries().size());
  SyncEntity entity = msg.commit().entries(0);
  ASSERT_TRUE(entity.specifics().has_password());

  // Verify the contents of the encrypted notes backup blob.
  sync_pb::PasswordSpecificsData_Notes decrypted_notes;
  cryptographer->Decrypt(entity.specifics().password().encrypted_notes_backup(),
                         &decrypted_notes);
  ASSERT_EQ(1, decrypted_notes.note_size());
  EXPECT_EQ(kNoteValue, decrypted_notes.note(0).value());
}

TEST(CommitContributionImplTest,
     ShouldPopulatePasswordNotesBackupWhenNoLocalNotes) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(syncer::kPasswordNotesWithBackup);

  auto data = std::make_unique<syncer::EntityData>();
  data->client_tag_hash = kTag;
  sync_pb::PasswordSpecificsData* password_data =
      data->specifics.mutable_password()->mutable_client_only_encrypted_data();
  password_data->set_signon_realm("signon_realm");

  auto request_data = std::make_unique<CommitRequestData>();
  base::Base64Encode(base::SHA1HashString(data->specifics.SerializeAsString()),
                     &request_data->specifics_hash);
  request_data->entity = std::move(data);

  CommitRequestDataList requests_data;
  requests_data.push_back(std::move(request_data));

  std::unique_ptr<FakeCryptographer> cryptographer =
      FakeCryptographer::FromSingleDefaultKey("dummy");
  CommitContributionImpl contribution(
      PASSWORDS, sync_pb::DataTypeContext(), std::move(requests_data),
      /*on_commit_response_callback=*/base::NullCallback(),
      /*on_full_commit_failure_callback=*/base::NullCallback(),
      cryptographer.get(), PassphraseType::kImplicitPassphrase,
      /*only_commit_specifics=*/false);

  sync_pb::ClientToServerMessage msg;
  contribution.AddToCommitMessage(&msg);

  ASSERT_EQ(1, msg.commit().entries().size());
  SyncEntity entity = msg.commit().entries(0);
  ASSERT_TRUE(entity.specifics().has_password());
  EXPECT_FALSE(
      entity.specifics().password().encrypted_notes_backup().blob().empty());
}

}  // namespace

}  // namespace syncer
