// Copyright 2019 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/sharing_message/sharing_service.h"

#include <memory>
#include <optional>
#include <vector>

#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/task/single_thread_task_runner.h"
#include "base/test/protobuf_matchers.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "base/uuid.h"
#include "components/favicon/core/test/mock_favicon_service.h"
#include "components/gcm_driver/crypto/gcm_encryption_provider.h"
#include "components/gcm_driver/instance_id/instance_id_driver.h"
#include "components/send_tab_to_self/features.h"
#include "components/send_tab_to_self/send_tab_to_self_entry.h"
#include "components/send_tab_to_self/test_send_tab_to_self_model.h"
#include "components/sharing_message/features.h"
#include "components/sharing_message/mock_sharing_device_source.h"
#include "components/sharing_message/mock_sharing_message_sender.h"
#include "components/sharing_message/proto/sharing_message.pb.h"
#include "components/sharing_message/sharing_constants.h"
#include "components/sharing_message/sharing_device_registration.h"
#include "components/sharing_message/sharing_device_registration_result.h"
#include "components/sharing_message/sharing_fcm_handler.h"
#include "components/sharing_message/sharing_fcm_sender.h"
#include "components/sharing_message/sharing_handler_registry.h"
#include "components/sharing_message/sharing_message_handler.h"
#include "components/sharing_message/sharing_sync_preference.h"
#include "components/strings/grit/components_strings.h"
#include "components/sync/protocol/unencrypted_sharing_message.pb.h"
#include "components/sync/test/test_sync_service.h"
#include "components/sync_device_info/device_info.h"
#include "components/sync_device_info/fake_device_info_sync_service.h"
#include "components/sync_device_info/local_device_info_provider.h"
#include "components/sync_device_info/local_device_info_util.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/gurl.h"

namespace {

const char kDeviceName[] = "other_name";
constexpr base::TimeDelta kTimeout = base::Seconds(15);

SharingTargetDeviceInfo CreateFakeSharingTargetDeviceInfo(
    const std::string& guid,
    const std::string& client_name) {
  return SharingTargetDeviceInfo(guid, client_name,
                                 SharingDevicePlatform::kUnknown,
                                 /*pulse_interval=*/base::TimeDelta(),
                                 syncer::DeviceInfo::FormFactor::kUnknown,
                                 /*last_updated_timestamp=*/base::Time());
}

class MockInstanceIDDriver : public instance_id::InstanceIDDriver {
 public:
  MockInstanceIDDriver() : InstanceIDDriver(/*gcm_driver=*/nullptr) {}

  MockInstanceIDDriver(const MockInstanceIDDriver&) = delete;
  MockInstanceIDDriver& operator=(const MockInstanceIDDriver&) = delete;

  ~MockInstanceIDDriver() override = default;
};

class MockSharingHandlerRegistry : public SharingHandlerRegistry {
 public:
  MockSharingHandlerRegistry() = default;
  ~MockSharingHandlerRegistry() override = default;

  MOCK_METHOD1(GetSharingHandler,
               SharingMessageHandler*(
                   components_sharing_message::SharingMessage::PayloadCase
                       payload_case));
  MOCK_METHOD2(RegisterSharingHandler,
               void(std::unique_ptr<SharingMessageHandler> handler,
                    components_sharing_message::SharingMessage::PayloadCase
                        payload_case));
  MOCK_METHOD1(UnregisterSharingHandler,
               void(components_sharing_message::SharingMessage::PayloadCase
                        payload_case));
};

class MockSharingFCMHandler : public SharingFCMHandler {
  using SharingMessage = components_sharing_message::SharingMessage;

 public:
  MockSharingFCMHandler()
      : SharingFCMHandler(/*gcm_driver=*/nullptr,
                          /*device_info_tracker=*/nullptr,
                          /*sharing_fcm_sender=*/nullptr,
                          /*handler_registry=*/nullptr) {}
  ~MockSharingFCMHandler() override = default;

  MOCK_METHOD0(StartListening, void());
  MOCK_METHOD0(StopListening, void());
};

class FakeSharingDeviceRegistration : public SharingDeviceRegistration {
 public:
  FakeSharingDeviceRegistration(
      PrefService* pref_service,
      SharingSyncPreference* prefs,
      instance_id::InstanceIDDriver* instance_id_driver,
      syncer::SyncService* sync_service) {}
  ~FakeSharingDeviceRegistration() override = default;

  void RegisterDevice(
      SharingDeviceRegistration::RegistrationCallback callback) override {
    registration_attempts_++;
    std::move(callback).Run(result_);
  }

  void UnregisterDevice(
      SharingDeviceRegistration::RegistrationCallback callback) override {
    unregistration_attempts_++;
    std::move(callback).Run(result_);
  }

  bool IsClickToCallSupported() const override { return false; }

  bool IsSharedClipboardSupported() const override { return false; }

  bool IsSmsFetcherSupported() const override { return false; }

  bool IsRemoteCopySupported() const override { return false; }

  bool IsOptimizationGuidePushNotificationSupported() const override {
    return false;
  }

  void SetEnabledFeaturesForTesting(
      std::set<sync_pb::SharingSpecificFields_EnabledFeatures> enabled_features)
      override {}

  void SetResult(SharingDeviceRegistrationResult result) { result_ = result; }

  int registration_attempts() { return registration_attempts_; }
  int unregistration_attempts() { return unregistration_attempts_; }

 private:
  SharingDeviceRegistrationResult result_ =
      SharingDeviceRegistrationResult::kSuccess;
  int registration_attempts_ = 0;
  int unregistration_attempts_ = 0;
};

class SharingServiceTest : public testing::Test {
 public:
  SharingServiceTest() {
    sync_prefs_ =
        new SharingSyncPreference(&prefs_, &fake_device_info_sync_service);
    sharing_device_registration_ = new FakeSharingDeviceRegistration(
        /* pref_service= */ nullptr, sync_prefs_, &mock_instance_id_driver_,
        &test_sync_service_);
    handler_registry_ = new testing::NiceMock<MockSharingHandlerRegistry>();
    fcm_handler_ = new testing::NiceMock<MockSharingFCMHandler>();
    device_source_ = new testing::NiceMock<MockSharingDeviceSource>();
    sharing_message_sender_ = new testing::NiceMock<MockSharingMessageSender>();
    SharingSyncPreference::RegisterProfilePrefs(prefs_.registry());

    ON_CALL(*device_source_, IsReady()).WillByDefault(testing::Return(true));
  }

  ~SharingServiceTest() override {
    // Make sure we're creating a SharingService so it can take ownership of the
    // local objects.
    SharingService* sharing_service = GetSharingService();

    // Avoid dangling pointers by resetting `raw_ptr`s before destroying/freeing
    // objects that they point to.
    sharing_device_registration_ = nullptr;

    // Go through the proper shutdown sequence to avoid hitting a `DCHECK` in
    // the destructor of the `SharingService`.
    static_cast<KeyedService*>(sharing_service)->Shutdown();
  }

  void OnMessageSent(
      SharingSendMessageResult result,
      std::unique_ptr<components_sharing_message::ResponseMessage> response) {
    send_message_result_ = std::make_optional(result);
    send_message_response_ = std::move(response);
  }

  const std::optional<SharingSendMessageResult>& send_message_result() {
    return send_message_result_;
  }

  const components_sharing_message::ResponseMessage* send_message_response() {
    return send_message_response_.get();
  }

  void OnDeviceCandidatesInitialized() {
    device_candidates_initialized_ = true;
  }

 protected:
  // Lazily initialized so we can test the constructor.
  SharingService* GetSharingService() {
    if (!sharing_service_) {
      sharing_service_ = std::make_unique<SharingService>(
          base::WrapUnique(sync_prefs_.get()),
          base::WrapUnique(sharing_device_registration_.get()),
          base::WrapUnique(sharing_message_sender_.get()),
          base::WrapUnique(device_source_.get()),
          base::WrapUnique(handler_registry_.get()),
          base::WrapUnique(fcm_handler_.get()), &test_sync_service_,
          &favicon_service_, &send_tab_to_self_model_,
          base::SingleThreadTaskRunner::GetCurrentDefault());
    }
    task_environment_.RunUntilIdle();
    return sharing_service_.get();
  }

  base::test::TaskEnvironment task_environment_{
      base::test::SingleThreadTaskEnvironment::MainThreadType::UI,
      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
  base::test::ScopedFeatureList scoped_features_;
  syncer::FakeDeviceInfoSyncService fake_device_info_sync_service;
  syncer::TestSyncService test_sync_service_;
  testing::NiceMock<favicon::MockFaviconService> favicon_service_;
  send_tab_to_self::TestSendTabToSelfModel send_tab_to_self_model_;
  sync_preferences::TestingPrefServiceSyncable prefs_;

 private:
  // `sharing_service_` must outlive the raw_ptrs below.
  std::unique_ptr<SharingService> sharing_service_;

 protected:
  testing::NiceMock<MockInstanceIDDriver> mock_instance_id_driver_;
  raw_ptr<testing::NiceMock<MockSharingHandlerRegistry>> handler_registry_;
  raw_ptr<testing::NiceMock<MockSharingFCMHandler>> fcm_handler_;
  raw_ptr<testing::NiceMock<MockSharingDeviceSource>> device_source_;

  raw_ptr<SharingSyncPreference> sync_prefs_;
  raw_ptr<FakeSharingDeviceRegistration> sharing_device_registration_;
  raw_ptr<testing::NiceMock<MockSharingMessageSender>> sharing_message_sender_;
  bool device_candidates_initialized_ = false;

 private:
  std::optional<SharingSendMessageResult> send_message_result_;
  std::unique_ptr<components_sharing_message::ResponseMessage>
      send_message_response_;
};

bool ProtoEquals(const google::protobuf::MessageLite& expected,
                 const google::protobuf::MessageLite& actual) {
  std::string expected_serialized, actual_serialized;
  expected.SerializeToString(&expected_serialized);
  actual.SerializeToString(&actual_serialized);
  return expected_serialized == actual_serialized;
}
}  // namespace

TEST_F(SharingServiceTest, GetDeviceCandidates_Empty) {
  EXPECT_CALL(*device_source_, GetDeviceCandidates(::testing::_))
      .WillOnce(
          [](sync_pb::SharingSpecificFields::EnabledFeatures required_feature)
              -> std::vector<SharingTargetDeviceInfo> { return {}; });

  std::vector<SharingTargetDeviceInfo> candidates =
      GetSharingService()->GetDeviceCandidates(
          sync_pb::SharingSpecificFields::CLICK_TO_CALL_V2);
  EXPECT_TRUE(candidates.empty());
}

TEST_F(SharingServiceTest, GetDeviceCandidates_Tracked) {
  EXPECT_CALL(*device_source_, GetDeviceCandidates(::testing::_))
      .WillOnce(
          [](sync_pb::SharingSpecificFields::EnabledFeatures required_feature) {
            std::vector<SharingTargetDeviceInfo> device_candidates;
            device_candidates.push_back(CreateFakeSharingTargetDeviceInfo(
                base::Uuid::GenerateRandomV4().AsLowercaseString(),
                kDeviceName));
            return device_candidates;
          });

  std::vector<SharingTargetDeviceInfo> candidates =
      GetSharingService()->GetDeviceCandidates(
          sync_pb::SharingSpecificFields::CLICK_TO_CALL_V2);

  ASSERT_EQ(1u, candidates.size());
}

TEST_F(SharingServiceTest, SendMessageToDeviceSuccess) {
  SharingTargetDeviceInfo device_info = CreateFakeSharingTargetDeviceInfo(
      base::Uuid::GenerateRandomV4().AsLowercaseString(), kDeviceName);

  components_sharing_message::ResponseMessage expected_response_message;

  auto run_callback = [&](const SharingTargetDeviceInfo& device_info,
                          base::TimeDelta response_timeout,
                          components_sharing_message::SharingMessage message,
                          SharingMessageSender::DelegateType delegate_type,
                          SharingMessageSender::ResponseCallback callback) {
    std::unique_ptr<components_sharing_message::ResponseMessage>
        response_message =
            std::make_unique<components_sharing_message::ResponseMessage>();
    response_message->CopyFrom(expected_response_message);
    std::move(callback).Run(SharingSendMessageResult::kSuccessful,
                            std::move(response_message));
    return base::DoNothing();
  };

  ON_CALL(*sharing_message_sender_,
          SendMessageToDevice(testing::_, testing::_, testing::_, testing::_,
                              testing::_))
      .WillByDefault(run_callback);

  GetSharingService()->SendMessageToDevice(
      device_info, kTimeout, components_sharing_message::SharingMessage(),
      base::BindOnce(&SharingServiceTest::OnMessageSent,
                     base::Unretained(this)));

  EXPECT_EQ(SharingSendMessageResult::kSuccessful, send_message_result());
  ASSERT_TRUE(send_message_response());
  EXPECT_TRUE(ProtoEquals(expected_response_message, *send_message_response()));
}

TEST_F(SharingServiceTest, SendTabEntryAddedLocally) {
  scoped_features_.InitAndEnableFeatureWithParameters(
      send_tab_to_self::kSendTabToSelfIOSPushNotifications,
      {{send_tab_to_self::kSendTabIOSPushNotificationsURLImageParam, "true"}});

  const std::string title = "title";
  const std::string device_name = "device name";
  const std::string host = "www.example.com";
  const std::string destination_url = "https://www.example.com/";
  const std::string icon_url = "https://www.example.com/favicon.ico";
  const std::string guid = base::Uuid::GenerateRandomV4().AsLowercaseString();

  EXPECT_CALL(*device_source_, GetDeviceByGuid(guid))
      .Times(2)
      .WillRepeatedly([](const std::string& guid)
                          -> std::optional<SharingTargetDeviceInfo> {
        return SharingTargetDeviceInfo(guid, kDeviceName,
                                       SharingDevicePlatform::kIOS,
                                       /*pulse_interval=*/base::TimeDelta(),
                                       syncer::DeviceInfo::FormFactor::kUnknown,
                                       /*last_updated_timestamp=*/base::Time());
      });

  ON_CALL(favicon_service_, GetLargestRawFaviconForPageURL)
      .WillByDefault([icon_url](auto, auto, auto,
                                favicon_base::FaviconRawBitmapCallback callback,
                                auto) {
        favicon_base::FaviconRawBitmapResult result;
        result.icon_url = GURL(icon_url);
        std::move(callback).Run(result);
        base::CancelableTaskTracker::TaskId kTaskId = 1;
        return kTaskId;
      });

  // Create the expected proto.
  sync_pb::UnencryptedSharingMessage message;
  sync_pb::SendTabToSelfPush* push_notification_entry =
      message.mutable_send_tab_message();
  push_notification_entry->set_title(l10n_util::GetStringFUTF8(
      IDS_SEND_TAB_PUSH_NOTIFICATION_TITLE_USER_GIVEN_DEVICE_NAME,
      base::UTF8ToUTF16(device_name)));
  push_notification_entry->set_text(l10n_util::GetStringFUTF8(
      IDS_SEND_TAB_PUSH_NOTIFICATION_BODY, base::UTF8ToUTF16(title),
      base::UTF8ToUTF16(host)));
  push_notification_entry->set_destination_url(destination_url);
  push_notification_entry->set_placeholder_title(l10n_util::GetStringUTF8(
      IDS_SEND_TAB_PUSH_NOTIFICATION_PLACEHOLDER_TITLE));
  push_notification_entry->set_placeholder_body(l10n_util::GetStringUTF8(
      IDS_SEND_TAB_PUSH_NOTIFICATION_PLACEHOLDER_BODY));
  push_notification_entry->set_entry_unique_guid(guid);
  auto* icon = push_notification_entry->add_icon();
  icon->set_url(icon_url);

  EXPECT_CALL(*sharing_message_sender_,
              SendUnencryptedMessageToDevice(testing::_,
                                             base::test::EqualsProto(message),
                                             testing::_, testing::_));

  send_tab_to_self::SendTabToSelfEntry entry =
      send_tab_to_self::SendTabToSelfEntry(guid, GURL(destination_url), title,
                                           base::Time(), device_name, guid);
  GetSharingService()->EntryAddedLocally(&entry);
}

TEST_F(SharingServiceTest, SendTabEntryAddedLocally_FeatureDisabled) {
  scoped_features_.InitAndDisableFeature(
      send_tab_to_self::kSendTabToSelfIOSPushNotifications);

  std::string guid = base::Uuid::GenerateRandomV4().AsLowercaseString();
  EXPECT_CALL(*device_source_, GetDeviceByGuid(guid)).Times(0);

  ON_CALL(favicon_service_, GetLargestRawFaviconForPageURL)
      .WillByDefault([](auto, auto, auto,
                        favicon_base::FaviconRawBitmapCallback callback, auto) {
        std::move(callback).Run(favicon_base::FaviconRawBitmapResult());
        base::CancelableTaskTracker::TaskId kTaskId = 1;
        return kTaskId;
      });

  EXPECT_CALL(*sharing_message_sender_, SendUnencryptedMessageToDevice)
      .Times(0);

  send_tab_to_self::SendTabToSelfEntry entry =
      send_tab_to_self::SendTabToSelfEntry(
          "guid", GURL("https://www.example.com"), "title", base::Time(),
          "device name", guid);
  GetSharingService()->EntryAddedLocally(&entry);
}

TEST_F(SharingServiceTest, SendTabEntryAddedLocally_NonIOSDevice) {
  scoped_features_.InitAndEnableFeature(
      send_tab_to_self::kSendTabToSelfIOSPushNotifications);

  std::string guid = base::Uuid::GenerateRandomV4().AsLowercaseString();

  EXPECT_CALL(*device_source_, GetDeviceByGuid(guid))
      .WillOnce([](const std::string& guid)
                    -> std::optional<SharingTargetDeviceInfo> {
        return SharingTargetDeviceInfo(guid, kDeviceName,
                                       SharingDevicePlatform::kAndroid,
                                       /*pulse_interval=*/base::TimeDelta(),
                                       syncer::DeviceInfo::FormFactor::kUnknown,
                                       /*last_updated_timestamp=*/base::Time());
      });

  EXPECT_CALL(*sharing_message_sender_, SendUnencryptedMessageToDevice)
      .Times(0);

  send_tab_to_self::SendTabToSelfEntry entry =
      send_tab_to_self::SendTabToSelfEntry(
          "guid", GURL("https://www.example.com"), "title", base::Time(),
          "device name", guid);
  GetSharingService()->EntryAddedLocally(&entry);
}

TEST_F(SharingServiceTest, DeviceRegistration) {
  test_sync_service_.GetUserSettings()->SetSelectedTypes(
      /*sync_everything=*/false,
      /*types=*/{syncer::UserSelectableType::kPreferences});

  EXPECT_EQ(SharingService::State::DISABLED,
            GetSharingService()->GetStateForTesting());

  // Expect registration to be successful on sync state changed.
  sharing_device_registration_->SetResult(
      SharingDeviceRegistrationResult::kSuccess);
  EXPECT_CALL(*fcm_handler_, StartListening()).Times(1);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(1, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(SharingService::State::ACTIVE,
            GetSharingService()->GetStateForTesting());

  // As device is already registered, won't attempt registration anymore.
  EXPECT_CALL(*fcm_handler_, StartListening()).Times(0);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(1, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(SharingService::State::ACTIVE,
            GetSharingService()->GetStateForTesting());
}

TEST_F(SharingServiceTest, DeviceRegistrationPreferenceNotAvailable) {
  test_sync_service_.GetUserSettings()->SetSelectedTypes(
      /*sync_everything=*/false,
      /*types=*/syncer::UserSelectableTypeSet());
  test_sync_service_.SetFailedDataTypes({syncer::SHARING_MESSAGE});

  EXPECT_EQ(SharingService::State::DISABLED,
            GetSharingService()->GetStateForTesting());

  // As sync preferences is not available, registration shouldn't start.
  EXPECT_CALL(*fcm_handler_, StartListening()).Times(0);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(0, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(SharingService::State::DISABLED,
            GetSharingService()->GetStateForTesting());
}

TEST_F(SharingServiceTest, DeviceRegistrationTransportMode) {
  EXPECT_EQ(SharingService::State::DISABLED,
            GetSharingService()->GetStateForTesting());

  // Expect registration to be successful on sync state changed.
  sharing_device_registration_->SetResult(
      SharingDeviceRegistrationResult::kSuccess);
  EXPECT_CALL(*fcm_handler_, StartListening()).Times(1);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(1, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(SharingService::State::ACTIVE,
            GetSharingService()->GetStateForTesting());
}

TEST_F(SharingServiceTest, DeviceRegistrationTransientError) {
  test_sync_service_.GetUserSettings()->SetSelectedTypes(
      /*sync_everything=*/false,
      /*types=*/{syncer::UserSelectableType::kPreferences});

  EXPECT_EQ(SharingService::State::DISABLED,
            GetSharingService()->GetStateForTesting());

  // Retry will be scheduled on transient error received.
  sharing_device_registration_->SetResult(
      SharingDeviceRegistrationResult::kFcmTransientError);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(1, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(SharingService::State::REGISTERING,
            GetSharingService()->GetStateForTesting());

  // Retry should be scheduled by now. Next retry after 5 minutes will be
  // successful.
  sharing_device_registration_->SetResult(
      SharingDeviceRegistrationResult::kSuccess);
  EXPECT_CALL(*fcm_handler_, StartListening()).Times(1);
  task_environment_.FastForwardBy(
      base::Milliseconds(kRetryBackoffPolicy.initial_delay_ms));
  EXPECT_EQ(2, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(SharingService::State::ACTIVE,
            GetSharingService()->GetStateForTesting());
}

TEST_F(SharingServiceTest, DeviceUnregistrationSyncDisabled) {
  test_sync_service_.SetSignedOut();

  // Create new SharingService instance with sync disabled at constructor.
  GetSharingService();
  EXPECT_EQ(1, sharing_device_registration_->unregistration_attempts());
  EXPECT_EQ(SharingService::State::DISABLED,
            GetSharingService()->GetStateForTesting());
}

TEST_F(SharingServiceTest, DeviceRegisterAndUnregister) {
  test_sync_service_.GetUserSettings()->SetSelectedTypes(
      /*sync_everything=*/false,
      /*types=*/{syncer::UserSelectableType::kPreferences});

  // Create new SharingService instance with feature enabled at constructor.
  GetSharingService();
  EXPECT_EQ(SharingService::State::DISABLED,
            GetSharingService()->GetStateForTesting());

  // Expect registration to be successful on sync state changed.
  sharing_device_registration_->SetResult(
      SharingDeviceRegistrationResult::kSuccess);
  EXPECT_CALL(*fcm_handler_, StartListening()).Times(1);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(1, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(0, sharing_device_registration_->unregistration_attempts());
  EXPECT_EQ(SharingService::State::ACTIVE,
            GetSharingService()->GetStateForTesting());

  // Further state changes do nothing.
  EXPECT_CALL(*fcm_handler_, StartListening()).Times(0);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(1, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(0, sharing_device_registration_->unregistration_attempts());
  EXPECT_EQ(SharingService::State::ACTIVE,
            GetSharingService()->GetStateForTesting());

  // Change sync to configuring, which will be ignored.
  test_sync_service_.SetMaxTransportState(
      syncer::SyncService::TransportState::CONFIGURING);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(1, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(0, sharing_device_registration_->unregistration_attempts());
  EXPECT_EQ(SharingService::State::ACTIVE,
            GetSharingService()->GetStateForTesting());

  // Disable sync and un-registration should happen.
  test_sync_service_.SetSignedOut();
  EXPECT_CALL(*fcm_handler_, StopListening()).Times(1);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(1, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(1, sharing_device_registration_->unregistration_attempts());
  EXPECT_EQ(SharingService::State::DISABLED,
            GetSharingService()->GetStateForTesting());

  // Further state changes do nothing.
  EXPECT_CALL(*fcm_handler_, StopListening()).Times(0);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(1, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(1, sharing_device_registration_->unregistration_attempts());
  EXPECT_EQ(SharingService::State::DISABLED,
            GetSharingService()->GetStateForTesting());

  // Should be able to register once again when sync is back on.
  test_sync_service_.SetMaxTransportState(
      syncer::SyncService::TransportState::ACTIVE);
  test_sync_service_.SetSignedIn(signin::ConsentLevel::kSync);
  EXPECT_CALL(*fcm_handler_, StartListening()).Times(1);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(2, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(1, sharing_device_registration_->unregistration_attempts());
  EXPECT_EQ(SharingService::State::ACTIVE,
            GetSharingService()->GetStateForTesting());

  // Disable syncing of preference and un-registration should happen.
  test_sync_service_.GetUserSettings()->SetSelectedTypes(
      /*sync_everything=*/false,
      /*types=*/syncer::UserSelectableTypeSet());
  test_sync_service_.SetFailedDataTypes({syncer::SHARING_MESSAGE});
  EXPECT_CALL(*fcm_handler_, StopListening()).Times(1);
  test_sync_service_.FireStateChanged();
  EXPECT_EQ(2, sharing_device_registration_->registration_attempts());
  EXPECT_EQ(2, sharing_device_registration_->unregistration_attempts());
  EXPECT_EQ(SharingService::State::DISABLED,
            GetSharingService()->GetStateForTesting());
}

TEST_F(SharingServiceTest, StartListeningToFCMAtConstructor) {
  test_sync_service_.GetUserSettings()->SetSelectedTypes(
      /*sync_everything=*/false,
      /*types=*/{syncer::UserSelectableType::kPreferences});

  // Create new SharingService instance with FCM already registered at
  // constructor.
  sync_prefs_->SetFCMRegistration(
      SharingSyncPreference::FCMRegistration(base::Time::Now()));
  EXPECT_CALL(*fcm_handler_, StartListening()).Times(1);
  GetSharingService();
}

TEST_F(SharingServiceTest, GetDeviceByGuid) {
  std::string guid = base::Uuid::GenerateRandomV4().AsLowercaseString();
  EXPECT_CALL(*device_source_, GetDeviceByGuid(guid))
      .WillOnce([](const std::string& guid)
                    -> std::optional<SharingTargetDeviceInfo> {
        return CreateFakeSharingTargetDeviceInfo(guid, "Dell Computer sno one");
      });

  std::optional<SharingTargetDeviceInfo> device_info =
      GetSharingService()->GetDeviceByGuid(guid);
  ASSERT_TRUE(device_info.has_value());
  EXPECT_EQ("Dell Computer sno one", device_info->client_name());
}

TEST_F(SharingServiceTest, AddSharingHandler) {
  EXPECT_CALL(*handler_registry_,
              RegisterSharingHandler(testing::_, testing::_))
      .Times(1);
  GetSharingService()->RegisterSharingHandler(
      nullptr,
      components_sharing_message::SharingMessage::kSharedClipboardMessage);
}

TEST_F(SharingServiceTest, RemoveSharingHandler) {
  EXPECT_CALL(*handler_registry_, UnregisterSharingHandler(testing::_))
      .Times(1);
  GetSharingService()->UnregisterSharingHandler(
      components_sharing_message::SharingMessage::kSharedClipboardMessage);
}
