// Copyright 2018 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/cryptauth/cryptauth_device_manager_impl.h"

#include <stddef.h>

#include <memory>
#include <utility>

#include "base/base64url.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/test/simple_test_clock.h"
#include "components/cryptauth/fake_cryptauth_gcm_manager.h"
#include "components/cryptauth/mock_cryptauth_client.h"
#include "components/cryptauth/mock_sync_scheduler.h"
#include "components/cryptauth/network_request_error.h"
#include "components/cryptauth/pref_names.h"
#include "components/cryptauth/proto/enum_util.h"
#include "components/cryptauth/software_feature_state.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/prefs/testing_pref_service.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::_;
using ::testing::DoAll;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;

namespace cryptauth {
namespace {

// The initial "Now" time for testing.
const double kInitialTimeNowSeconds = 20000000;

// A later "Now" time for testing.
const double kLaterTimeNowSeconds = kInitialTimeNowSeconds + 30;

// The timestamp of a last successful sync in seconds.
const double kLastSyncTimeSeconds = kInitialTimeNowSeconds - (60 * 60 * 5);

// Unlock key fields originally stored in the user prefs.
const char kStoredPublicKey[] = "storedPublicKey";
const char kStoredDeviceName[] = "Pixel 2";
const char kStoredBluetoothAddress[] = "12:34:56:78:90:AB";
const bool kStoredUnlockable = false;

// ExternalDeviceInfo fields for the synced unlock key.
const char kPublicKey1[] = "GOOG";
const char kDeviceName1[] = "Pixel XL";
const char kBluetoothAddress1[] = "aa:bb:cc:ee:dd:ff";
const bool kUnlockable1 = false;
const char kBeaconSeed1Data[] = "beaconSeed1Data";
const int64_t kBeaconSeed1StartTime = 123456;
const int64_t kBeaconSeed1EndTime = 123457;
const char kBeaconSeed2Data[] = "beaconSeed2Data";
const int64_t kBeaconSeed2StartTime = 234567;
const int64_t kBeaconSeed2EndTime = 234568;
const bool kArcPlusPlus1 = true;
const bool kPixelPhone1 = true;

// ExternalDeviceInfo fields for a non-synced unlockable device.
const char kPublicKey2[] = "CROS";
const char kDeviceName2[] = "Pixelbook";
const bool kUnlockable2 = true;
const char kBeaconSeed3Data[] = "beaconSeed3Data";
const int64_t kBeaconSeed3StartTime = 123456;
const int64_t kBeaconSeed3EndTime = 123457;
const char kBeaconSeed4Data[] = "beaconSeed4Data";
const int64_t kBeaconSeed4StartTime = 234567;
const int64_t kBeaconSeed4EndTime = 234568;
const bool kArcPlusPlus2 = false;
const bool kPixelPhone2 = false;

// Validates that |devices| is equal to |expected_devices|.
void ExpectSyncedDevicesAreEqual(
    const std::vector<ExternalDeviceInfo>& expected_devices,
    const std::vector<ExternalDeviceInfo>& devices) {
  ASSERT_EQ(expected_devices.size(), devices.size());
  for (size_t i = 0; i < devices.size(); ++i) {
    SCOPED_TRACE(
        base::StringPrintf("Compare protos at index=%d", static_cast<int>(i)));
    const auto& expected_device = expected_devices[i];
    const auto& device = devices.at(i);
    EXPECT_TRUE(expected_device.has_public_key());
    EXPECT_TRUE(device.has_public_key());
    EXPECT_EQ(expected_device.public_key(), device.public_key());

    EXPECT_EQ(expected_device.has_friendly_device_name(),
              device.has_friendly_device_name());
    EXPECT_EQ(expected_device.friendly_device_name(),
              device.friendly_device_name());

    EXPECT_EQ(expected_device.has_bluetooth_address(),
              device.has_bluetooth_address());
    EXPECT_EQ(expected_device.bluetooth_address(), device.bluetooth_address());

    EXPECT_EQ(expected_device.has_unlock_key(), device.has_unlock_key());
    EXPECT_EQ(expected_device.unlock_key(), device.unlock_key());

    EXPECT_EQ(expected_device.has_unlockable(), device.has_unlockable());
    EXPECT_EQ(expected_device.unlockable(), device.unlockable());

    EXPECT_EQ(expected_device.has_last_update_time_millis(),
              device.has_last_update_time_millis());
    EXPECT_EQ(expected_device.last_update_time_millis(),
              device.last_update_time_millis());

    EXPECT_EQ(expected_device.has_mobile_hotspot_supported(),
              device.has_mobile_hotspot_supported());
    EXPECT_EQ(expected_device.mobile_hotspot_supported(),
              device.mobile_hotspot_supported());

    EXPECT_EQ(expected_device.has_device_type(), device.has_device_type());
    EXPECT_EQ(expected_device.device_type(), device.device_type());

    ASSERT_EQ(expected_device.beacon_seeds_size(), device.beacon_seeds_size());
    for (int i = 0; i < expected_device.beacon_seeds_size(); i++) {
      const BeaconSeed expected_seed = expected_device.beacon_seeds(i);
      const BeaconSeed seed = device.beacon_seeds(i);
      EXPECT_TRUE(expected_seed.has_data());
      EXPECT_TRUE(seed.has_data());
      EXPECT_EQ(expected_seed.data(), seed.data());

      EXPECT_TRUE(expected_seed.has_start_time_millis());
      EXPECT_TRUE(seed.has_start_time_millis());
      EXPECT_EQ(expected_seed.start_time_millis(), seed.start_time_millis());

      EXPECT_TRUE(expected_seed.has_end_time_millis());
      EXPECT_TRUE(seed.has_end_time_millis());
      EXPECT_EQ(expected_seed.end_time_millis(), seed.end_time_millis());
    }

    EXPECT_EQ(expected_device.has_arc_plus_plus(), device.has_arc_plus_plus());
    EXPECT_EQ(expected_device.arc_plus_plus(), device.arc_plus_plus());

    EXPECT_EQ(expected_device.has_pixel_phone(), device.has_pixel_phone());
    EXPECT_EQ(expected_device.pixel_phone(), device.pixel_phone());

    EXPECT_EQ(expected_device.supported_software_features_size(),
              device.supported_software_features_size());
    for (const auto& software_feature :
         expected_device.supported_software_features()) {
      EXPECT_TRUE(base::ContainsValue(device.supported_software_features(),
                                      software_feature));
    }

    EXPECT_EQ(expected_device.enabled_software_features_size(),
              device.enabled_software_features_size());
    for (const auto& software_feature :
         expected_device.enabled_software_features()) {
      EXPECT_TRUE(base::ContainsValue(device.enabled_software_features(),
                                      software_feature));
    }
  }
}

// Validates that |devices| and the corresponding preferences stored by
// |pref_service| are equal to |expected_devices|.
void ExpectSyncedDevicesAndPrefAreEqual(
    const std::vector<ExternalDeviceInfo>& expected_devices,
    const std::vector<ExternalDeviceInfo>& devices,
    const PrefService& pref_service) {
  ExpectSyncedDevicesAreEqual(expected_devices, devices);

  const base::ListValue* synced_devices_pref =
      pref_service.GetList(prefs::kCryptAuthDeviceSyncUnlockKeys);
  ASSERT_EQ(expected_devices.size(), synced_devices_pref->GetSize());
  for (size_t i = 0; i < synced_devices_pref->GetSize(); ++i) {
    SCOPED_TRACE(base::StringPrintf("Compare pref dictionary at index=%d",
                                    static_cast<int>(i)));
    const base::DictionaryValue* device_dictionary;
    EXPECT_TRUE(synced_devices_pref->GetDictionary(i, &device_dictionary));

    const auto& expected_device = expected_devices[i];

    std::string public_key_b64, public_key;
    EXPECT_TRUE(device_dictionary->GetString("public_key", &public_key_b64));
    EXPECT_TRUE(base::Base64UrlDecode(
        public_key_b64, base::Base64UrlDecodePolicy::REQUIRE_PADDING,
        &public_key));
    EXPECT_TRUE(expected_device.has_public_key());
    EXPECT_EQ(expected_device.public_key(), public_key);

    std::string device_name_b64, device_name;
    if (device_dictionary->GetString("device_name", &device_name_b64)) {
      EXPECT_TRUE(base::Base64UrlDecode(
          device_name_b64, base::Base64UrlDecodePolicy::REQUIRE_PADDING,
          &device_name));
      EXPECT_TRUE(expected_device.has_friendly_device_name());
      EXPECT_EQ(expected_device.friendly_device_name(), device_name);
    } else {
      EXPECT_FALSE(expected_device.has_friendly_device_name());
    }

    std::string bluetooth_address_b64, bluetooth_address;
    if (device_dictionary->GetString("bluetooth_address",
                                     &bluetooth_address_b64)) {
      EXPECT_TRUE(base::Base64UrlDecode(
          bluetooth_address_b64, base::Base64UrlDecodePolicy::REQUIRE_PADDING,
          &bluetooth_address));
      EXPECT_TRUE(expected_device.has_bluetooth_address());
      EXPECT_EQ(expected_device.bluetooth_address(), bluetooth_address);
    } else {
      EXPECT_FALSE(expected_device.has_bluetooth_address());
    }

    bool unlock_key;
    if (device_dictionary->GetBoolean("unlock_key", &unlock_key)) {
      EXPECT_TRUE(expected_device.has_unlock_key());
      EXPECT_EQ(expected_device.unlock_key(), unlock_key);
    } else {
      EXPECT_FALSE(expected_device.has_unlock_key());
    }

    bool unlockable;
    if (device_dictionary->GetBoolean("unlockable", &unlockable)) {
      EXPECT_TRUE(expected_device.has_unlockable());
      EXPECT_EQ(expected_device.unlockable(), unlockable);
    } else {
      EXPECT_FALSE(expected_device.has_unlockable());
    }

    std::string last_update_time_millis_str;
    if (device_dictionary->GetString("last_update_time_millis",
                                     &last_update_time_millis_str)) {
      int64_t last_update_time_millis;
      EXPECT_TRUE(base::StringToInt64(last_update_time_millis_str,
                                      &last_update_time_millis));
      EXPECT_TRUE(expected_device.has_last_update_time_millis());
      EXPECT_EQ(expected_device.last_update_time_millis(),
                last_update_time_millis);
    } else {
      EXPECT_FALSE(expected_device.has_last_update_time_millis());
    }

    bool mobile_hotspot_supported;
    if (device_dictionary->GetBoolean("mobile_hotspot_supported",
                                      &mobile_hotspot_supported)) {
      EXPECT_TRUE(expected_device.has_mobile_hotspot_supported());
      EXPECT_EQ(expected_device.mobile_hotspot_supported(),
                mobile_hotspot_supported);
    } else {
      EXPECT_FALSE(expected_device.has_mobile_hotspot_supported());
    }

    int device_type;
    if (device_dictionary->GetInteger("device_type", &device_type)) {
      EXPECT_TRUE(expected_device.has_device_type());
      EXPECT_EQ(expected_device.device_type(), device_type);
    } else {
      EXPECT_FALSE(expected_device.has_device_type());
    }

    const base::ListValue* beacon_seeds_from_prefs;
    if (device_dictionary->GetList("beacon_seeds", &beacon_seeds_from_prefs)) {
      ASSERT_EQ(static_cast<size_t>(expected_device.beacon_seeds_size()),
                beacon_seeds_from_prefs->GetSize());
      for (size_t i = 0; i < beacon_seeds_from_prefs->GetSize(); i++) {
        const base::DictionaryValue* seed;
        ASSERT_TRUE(beacon_seeds_from_prefs->GetDictionary(i, &seed));

        std::string data_b64, start_ms, end_ms;
        EXPECT_TRUE(seed->GetString("beacon_seed_data", &data_b64));
        EXPECT_TRUE(seed->GetString("beacon_seed_start_ms", &start_ms));
        EXPECT_TRUE(seed->GetString("beacon_seed_end_ms", &end_ms));

        const BeaconSeed& expected_seed = expected_device.beacon_seeds((int)i);

        std::string data;
        EXPECT_TRUE(base::Base64UrlDecode(
            data_b64, base::Base64UrlDecodePolicy::REQUIRE_PADDING, &data));
        EXPECT_TRUE(expected_seed.has_data());
        EXPECT_EQ(expected_seed.data(), data);

        EXPECT_TRUE(expected_seed.has_start_time_millis());
        EXPECT_EQ(expected_seed.start_time_millis(), std::stol(start_ms));

        EXPECT_TRUE(expected_seed.has_end_time_millis());
        EXPECT_EQ(expected_seed.end_time_millis(), std::stol(end_ms));
      }
    } else {
      EXPECT_FALSE(expected_device.beacon_seeds_size());
    }

    bool arc_plus_plus;
    if (device_dictionary->GetBoolean("arc_plus_plus", &arc_plus_plus)) {
      EXPECT_TRUE(expected_device.has_arc_plus_plus());
      EXPECT_EQ(expected_device.arc_plus_plus(), arc_plus_plus);
    } else {
      EXPECT_FALSE(expected_device.has_arc_plus_plus());
    }

    bool pixel_phone;
    if (device_dictionary->GetBoolean("pixel_phone", &pixel_phone)) {
      EXPECT_TRUE(expected_device.has_pixel_phone());
      EXPECT_EQ(expected_device.pixel_phone(), pixel_phone);
    } else {
      EXPECT_FALSE(expected_device.has_pixel_phone());
    }

    const base::DictionaryValue* software_features_from_prefs;
    if (device_dictionary->GetDictionary("software_features",
                                         &software_features_from_prefs)) {
      std::vector<SoftwareFeature> supported_software_features;
      std::vector<SoftwareFeature> enabled_software_features;

      for (const auto& it : software_features_from_prefs->DictItems()) {
        int software_feature_state;
        ASSERT_TRUE(it.second.GetAsInteger(&software_feature_state));

        SoftwareFeature software_feature =
            SoftwareFeatureStringToEnum(it.first);
        switch (static_cast<SoftwareFeatureState>(software_feature_state)) {
          case SoftwareFeatureState::kEnabled:
            enabled_software_features.push_back(software_feature);
            FALLTHROUGH;
          case SoftwareFeatureState::kSupported:
            supported_software_features.push_back(software_feature);
            break;
          default:
            break;
        }
      }

      ASSERT_EQ(static_cast<size_t>(
                    expected_device.supported_software_features_size()),
                supported_software_features.size());
      ASSERT_EQ(
          static_cast<size_t>(expected_device.enabled_software_features_size()),
          enabled_software_features.size());
      for (auto supported_software_feature :
           expected_device.supported_software_features()) {
        EXPECT_TRUE(base::ContainsValue(
            supported_software_features,
            SoftwareFeatureStringToEnum(supported_software_feature)));
      }
      for (auto enabled_software_feature :
           expected_device.enabled_software_features()) {
        EXPECT_TRUE(base::ContainsValue(
            enabled_software_features,
            SoftwareFeatureStringToEnum(enabled_software_feature)));
      }
    } else {
      EXPECT_FALSE(expected_device.supported_software_features_size());
      EXPECT_FALSE(expected_device.enabled_software_features_size());
    }
  }
}

// Harness for testing CryptAuthDeviceManager.
class TestCryptAuthDeviceManager : public CryptAuthDeviceManagerImpl {
 public:
  TestCryptAuthDeviceManager(base::Clock* clock,
                             CryptAuthClientFactory* client_factory,
                             CryptAuthGCMManager* gcm_manager,
                             PrefService* pref_service)
      : CryptAuthDeviceManagerImpl(clock,
                                   client_factory,
                                   gcm_manager,
                                   pref_service),
        scoped_sync_scheduler_(new NiceMock<MockSyncScheduler>()),
        weak_sync_scheduler_factory_(scoped_sync_scheduler_) {
    SetSyncSchedulerForTest(base::WrapUnique(scoped_sync_scheduler_));
  }

  ~TestCryptAuthDeviceManager() override {}

  base::WeakPtr<MockSyncScheduler> GetSyncScheduler() {
    return weak_sync_scheduler_factory_.GetWeakPtr();
  }

 private:
  // Ownership is passed to |CryptAuthDeviceManager| super class when
  // SetSyncSchedulerForTest() is called.
  MockSyncScheduler* scoped_sync_scheduler_;

  // Stores the pointer of |scoped_sync_scheduler_| after ownership is passed to
  // the super class.
  // This should be safe because the life-time this SyncScheduler will always be
  // within the life of the TestCryptAuthDeviceManager object.
  base::WeakPtrFactory<MockSyncScheduler> weak_sync_scheduler_factory_;

  DISALLOW_COPY_AND_ASSIGN(TestCryptAuthDeviceManager);
};

}  // namespace

class CryptAuthDeviceManagerImplTest
    : public testing::Test,
      public CryptAuthDeviceManager::Observer,
      public MockCryptAuthClientFactory::Observer {
 protected:
  CryptAuthDeviceManagerImplTest()
      : client_factory_(std::make_unique<MockCryptAuthClientFactory>(
            MockCryptAuthClientFactory::MockType::MAKE_STRICT_MOCKS)),
        gcm_manager_("existing gcm registration id") {
    client_factory_->AddObserver(this);

    ExternalDeviceInfo unlock_key;
    unlock_key.set_public_key(kPublicKey1);
    unlock_key.set_friendly_device_name(kDeviceName1);
    unlock_key.set_bluetooth_address(kBluetoothAddress1);
    unlock_key.set_unlockable(kUnlockable1);
    BeaconSeed* seed1 = unlock_key.add_beacon_seeds();
    seed1->set_data(kBeaconSeed1Data);
    seed1->set_start_time_millis(kBeaconSeed1StartTime);
    seed1->set_end_time_millis(kBeaconSeed1EndTime);
    BeaconSeed* seed2 = unlock_key.add_beacon_seeds();
    seed2->set_data(kBeaconSeed2Data);
    seed2->set_start_time_millis(kBeaconSeed2StartTime);
    seed2->set_end_time_millis(kBeaconSeed2EndTime);
    unlock_key.set_arc_plus_plus(kArcPlusPlus1);
    unlock_key.set_pixel_phone(kPixelPhone1);
    unlock_key.add_supported_software_features(
        SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST));
    unlock_key.add_enabled_software_features(
        SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST));
    unlock_key.add_supported_software_features(
        SoftwareFeatureEnumToString(SoftwareFeature::BETTER_TOGETHER_HOST));
    unlock_key.add_supported_software_features(
        SoftwareFeatureEnumToString(SoftwareFeature::BETTER_TOGETHER_CLIENT));
    unlock_key.add_enabled_software_features(
        SoftwareFeatureEnumToString(SoftwareFeature::BETTER_TOGETHER_HOST));
    devices_in_response_.push_back(unlock_key);

    ExternalDeviceInfo unlockable_device;
    unlockable_device.set_public_key(kPublicKey2);
    unlockable_device.set_friendly_device_name(kDeviceName2);
    unlockable_device.set_unlockable(kUnlockable2);
    BeaconSeed* seed3 = unlockable_device.add_beacon_seeds();
    seed3->set_data(kBeaconSeed3Data);
    seed3->set_start_time_millis(kBeaconSeed3StartTime);
    seed3->set_end_time_millis(kBeaconSeed3EndTime);
    BeaconSeed* seed4 = unlockable_device.add_beacon_seeds();
    seed4->set_data(kBeaconSeed4Data);
    seed4->set_start_time_millis(kBeaconSeed4StartTime);
    seed4->set_end_time_millis(kBeaconSeed4EndTime);
    unlockable_device.set_arc_plus_plus(kArcPlusPlus2);
    unlockable_device.set_pixel_phone(kPixelPhone2);
    unlockable_device.add_supported_software_features(
        SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_HOST));
    unlockable_device.add_supported_software_features(
        SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_CLIENT));
    unlockable_device.add_enabled_software_features(
        SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_HOST));
    devices_in_response_.push_back(unlockable_device);
  }

  ~CryptAuthDeviceManagerImplTest() { client_factory_->RemoveObserver(this); }

  // testing::Test:
  void SetUp() override {
    clock_.SetNow(base::Time::FromDoubleT(kInitialTimeNowSeconds));

    CryptAuthDeviceManager::RegisterPrefs(pref_service_.registry());
    pref_service_.SetUserPref(
        prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure,
        std::make_unique<base::Value>(false));
    pref_service_.SetUserPref(
        prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds,
        std::make_unique<base::Value>(kLastSyncTimeSeconds));
    pref_service_.SetUserPref(
        prefs::kCryptAuthDeviceSyncReason,
        std::make_unique<base::Value>(INVOCATION_REASON_UNKNOWN));

    std::unique_ptr<base::DictionaryValue> device_dictionary(
        new base::DictionaryValue());

    std::string public_key_b64, device_name_b64, bluetooth_address_b64;
    base::Base64UrlEncode(kStoredPublicKey,
                          base::Base64UrlEncodePolicy::INCLUDE_PADDING,
                          &public_key_b64);
    base::Base64UrlEncode(kStoredDeviceName,
                          base::Base64UrlEncodePolicy::INCLUDE_PADDING,
                          &device_name_b64);
    base::Base64UrlEncode(kStoredBluetoothAddress,
                          base::Base64UrlEncodePolicy::INCLUDE_PADDING,
                          &bluetooth_address_b64);

    device_dictionary->SetString("public_key", public_key_b64);
    device_dictionary->SetString("device_name", device_name_b64);
    device_dictionary->SetString("bluetooth_address", bluetooth_address_b64);
    device_dictionary->SetBoolean("unlockable", kStoredUnlockable);
    device_dictionary->Set("beacon_seeds", std::make_unique<base::ListValue>());
    device_dictionary->Set("software_features",
                           std::make_unique<base::DictionaryValue>());

    {
      ListPrefUpdate update(&pref_service_,
                            prefs::kCryptAuthDeviceSyncUnlockKeys);
      update.Get()->Append(std::move(device_dictionary));
    }

    device_manager_.reset(new TestCryptAuthDeviceManager(
        &clock_, client_factory_.get(), &gcm_manager_, &pref_service_));
    device_manager_->AddObserver(this);

    get_my_devices_response_.add_devices()->CopyFrom(devices_in_response_[0]);
    get_my_devices_response_.add_devices()->CopyFrom(devices_in_response_[1]);

    ON_CALL(*sync_scheduler(), GetStrategy())
        .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH));
  }

  void TearDown() override { device_manager_->RemoveObserver(this); }

  // CryptAuthDeviceManager::Observer:
  void OnSyncStarted() override { OnSyncStartedProxy(); }

  void OnSyncFinished(CryptAuthDeviceManager::SyncResult sync_result,
                      CryptAuthDeviceManager::DeviceChangeResult
                          device_change_result) override {
    OnSyncFinishedProxy(sync_result, device_change_result);
  }

  MOCK_METHOD0(OnSyncStartedProxy, void());
  MOCK_METHOD2(OnSyncFinishedProxy,
               void(CryptAuthDeviceManager::SyncResult,
                    CryptAuthDeviceManager::DeviceChangeResult));

  // Simulates firing the SyncScheduler to trigger a device sync attempt.
  void FireSchedulerForSync(InvocationReason expected_invocation_reason) {
    SyncScheduler::Delegate* delegate =
        static_cast<SyncScheduler::Delegate*>(device_manager_.get());

    std::unique_ptr<SyncScheduler::SyncRequest> sync_request =
        std::make_unique<SyncScheduler::SyncRequest>(
            device_manager_->GetSyncScheduler());
    EXPECT_CALL(*this, OnSyncStartedProxy());
    delegate->OnSyncRequested(std::move(sync_request));

    EXPECT_EQ(expected_invocation_reason,
              get_my_devices_request_.invocation_reason());

    // The allow_stale_read flag is set if the sync was not forced.
    bool allow_stale_read =
        pref_service_.GetInteger(prefs::kCryptAuthDeviceSyncReason) !=
        INVOCATION_REASON_UNKNOWN;
    EXPECT_EQ(allow_stale_read, get_my_devices_request_.allow_stale_read());
  }

  // MockCryptAuthClientFactory::Observer:
  void OnCryptAuthClientCreated(MockCryptAuthClient* client) override {
    EXPECT_CALL(*client, GetMyDevices(_, _, _, _))
        .WillOnce(DoAll(SaveArg<0>(&get_my_devices_request_),
                        SaveArg<1>(&success_callback_),
                        SaveArg<2>(&error_callback_)));
  }

  MockSyncScheduler* sync_scheduler() {
    return device_manager_->GetSyncScheduler().get();
  }

  base::SimpleTestClock clock_;

  std::unique_ptr<MockCryptAuthClientFactory> client_factory_;

  TestingPrefServiceSimple pref_service_;

  FakeCryptAuthGCMManager gcm_manager_;

  std::unique_ptr<TestCryptAuthDeviceManager> device_manager_;

  std::vector<ExternalDeviceInfo> devices_in_response_;

  GetMyDevicesResponse get_my_devices_response_;

  GetMyDevicesRequest get_my_devices_request_;

  CryptAuthClient::GetMyDevicesCallback success_callback_;

  CryptAuthClient::ErrorCallback error_callback_;

  DISALLOW_COPY_AND_ASSIGN(CryptAuthDeviceManagerImplTest);
};

TEST_F(CryptAuthDeviceManagerImplTest, RegisterPrefs) {
  TestingPrefServiceSimple pref_service;
  CryptAuthDeviceManager::RegisterPrefs(pref_service.registry());
  EXPECT_TRUE(pref_service.FindPreference(
      prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds));
  EXPECT_TRUE(pref_service.FindPreference(
      prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure));
  EXPECT_TRUE(pref_service.FindPreference(prefs::kCryptAuthDeviceSyncReason));
  EXPECT_TRUE(
      pref_service.FindPreference(prefs::kCryptAuthDeviceSyncUnlockKeys));
}

TEST_F(CryptAuthDeviceManagerImplTest, GetSyncState) {
  device_manager_->Start();

  ON_CALL(*sync_scheduler(), GetStrategy())
      .WillByDefault(Return(SyncScheduler::Strategy::PERIODIC_REFRESH));
  EXPECT_FALSE(device_manager_->IsRecoveringFromFailure());

  ON_CALL(*sync_scheduler(), GetStrategy())
      .WillByDefault(Return(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY));
  EXPECT_TRUE(device_manager_->IsRecoveringFromFailure());

  base::TimeDelta time_to_next_sync = base::TimeDelta::FromMinutes(60);
  ON_CALL(*sync_scheduler(), GetTimeToNextSync())
      .WillByDefault(Return(time_to_next_sync));
  EXPECT_EQ(time_to_next_sync, device_manager_->GetTimeToNextAttempt());

  ON_CALL(*sync_scheduler(), GetSyncState())
      .WillByDefault(Return(SyncScheduler::SyncState::SYNC_IN_PROGRESS));
  EXPECT_TRUE(device_manager_->IsSyncInProgress());

  ON_CALL(*sync_scheduler(), GetSyncState())
      .WillByDefault(Return(SyncScheduler::SyncState::WAITING_FOR_REFRESH));
  EXPECT_FALSE(device_manager_->IsSyncInProgress());
}

TEST_F(CryptAuthDeviceManagerImplTest, InitWithDefaultPrefs) {
  base::SimpleTestClock clock;
  clock.SetNow(base::Time::FromDoubleT(kInitialTimeNowSeconds));
  base::TimeDelta elapsed_time = clock.Now() - base::Time::FromDoubleT(0);

  TestingPrefServiceSimple pref_service;
  CryptAuthDeviceManager::RegisterPrefs(pref_service.registry());

  TestCryptAuthDeviceManager device_manager(&clock, client_factory_.get(),
                                            &gcm_manager_, &pref_service);

  EXPECT_CALL(
      *(device_manager.GetSyncScheduler()),
      Start(elapsed_time, SyncScheduler::Strategy::AGGRESSIVE_RECOVERY));
  device_manager.Start();
  EXPECT_TRUE(device_manager.GetLastSyncTime().is_null());
  EXPECT_EQ(0u, device_manager.GetSyncedDevices().size());
}

TEST_F(CryptAuthDeviceManagerImplTest, InitWithExistingPrefs) {
  EXPECT_CALL(
      *sync_scheduler(),
      Start(clock_.Now() - base::Time::FromDoubleT(kLastSyncTimeSeconds),
            SyncScheduler::Strategy::PERIODIC_REFRESH));

  device_manager_->Start();
  EXPECT_EQ(base::Time::FromDoubleT(kLastSyncTimeSeconds),
            device_manager_->GetLastSyncTime());

  auto synced_devices = device_manager_->GetSyncedDevices();
  ASSERT_EQ(1u, synced_devices.size());
  EXPECT_EQ(kStoredPublicKey, synced_devices[0].public_key());
  EXPECT_EQ(kStoredDeviceName, synced_devices[0].friendly_device_name());
  EXPECT_EQ(kStoredBluetoothAddress, synced_devices[0].bluetooth_address());
  EXPECT_EQ(kStoredUnlockable, synced_devices[0].unlockable());
}

// ExternalDeviceInfos's |unlock_key| and |mobile_hotspot_supported| fields
// are deprecated, but it may be the case that after an update to Chrome, the
// prefs reflect the old style of using these deprecated fields, instead of
// software features. This test ensures the CryptAuthDeviceManager considers
// these deprecated booleans, and populates the correct software features.
TEST_F(
    CryptAuthDeviceManagerImplTest,
    InitWithExistingPrefs_MigrateDeprecateBooleansFromPrefsToSoftwareFeature) {
  ListPrefUpdate update_clear(&pref_service_,
                              prefs::kCryptAuthDeviceSyncUnlockKeys);
  update_clear.Get()->Clear();

  // Simulate a deprecated device being persisted to prefs.
  auto device_dictionary = std::make_unique<base::DictionaryValue>();
  std::string public_key_b64;
  base::Base64UrlEncode(kStoredPublicKey,
                        base::Base64UrlEncodePolicy::INCLUDE_PADDING,
                        &public_key_b64);
  device_dictionary->SetString("public_key", public_key_b64);
  device_dictionary->SetBoolean("unlock_key", true);
  device_dictionary->SetBoolean("mobile_hotspot_supported", true);
  device_dictionary->Set("software_features",
                         std::make_unique<base::DictionaryValue>());

  ListPrefUpdate update(&pref_service_, prefs::kCryptAuthDeviceSyncUnlockKeys);
  update.Get()->Append(std::move(device_dictionary));

  device_manager_.reset(new TestCryptAuthDeviceManager(
      &clock_, client_factory_.get(), &gcm_manager_, &pref_service_));
  device_manager_->Start();

  // Ensure that the deprecated booleans are not exposed in the final
  // ExternalDeviceInfo, but rather in the correct software features.
  auto synced_devices = device_manager_->GetSyncedDevices();
  ASSERT_EQ(1u, synced_devices.size());
  EXPECT_EQ(kStoredPublicKey, synced_devices[0].public_key());
  EXPECT_FALSE(synced_devices[0].unlock_key());
  EXPECT_FALSE(synced_devices[0].mobile_hotspot_supported());

  EXPECT_EQ(2, synced_devices[0].supported_software_features().size());
  EXPECT_TRUE(base::ContainsValue(
      synced_devices[0].supported_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST)));
  EXPECT_TRUE(base::ContainsValue(
      synced_devices[0].supported_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_HOST)));
  EXPECT_EQ(1, synced_devices[0].enabled_software_features().size());
  EXPECT_TRUE(base::ContainsValue(
      synced_devices[0].enabled_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST)));
}

TEST_F(CryptAuthDeviceManagerImplTest, SyncSucceedsForFirstTime) {
  pref_service_.ClearPref(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds);
  device_manager_->Start();

  FireSchedulerForSync(INVOCATION_REASON_INITIALIZATION);
  ASSERT_FALSE(success_callback_.is_null());

  clock_.SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds));
  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));

  success_callback_.Run(get_my_devices_response_);
  EXPECT_EQ(clock_.Now(), device_manager_->GetLastSyncTime());

  ExpectSyncedDevicesAndPrefAreEqual(
      devices_in_response_, device_manager_->GetSyncedDevices(), pref_service_);
}

TEST_F(CryptAuthDeviceManagerImplTest, ForceSync) {
  device_manager_->Start();

  EXPECT_CALL(*sync_scheduler(), ForceSync());
  device_manager_->ForceSyncNow(INVOCATION_REASON_MANUAL);

  FireSchedulerForSync(INVOCATION_REASON_MANUAL);

  clock_.SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds));
  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
  success_callback_.Run(get_my_devices_response_);
  EXPECT_EQ(clock_.Now(), device_manager_->GetLastSyncTime());

  ExpectSyncedDevicesAndPrefAreEqual(
      devices_in_response_, device_manager_->GetSyncedDevices(), pref_service_);
}

TEST_F(CryptAuthDeviceManagerImplTest, ForceSyncFailsThenSucceeds) {
  device_manager_->Start();
  EXPECT_FALSE(pref_service_.GetBoolean(
      prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure));
  base::Time old_sync_time = device_manager_->GetLastSyncTime();

  // The first force sync fails.
  EXPECT_CALL(*sync_scheduler(), ForceSync());
  device_manager_->ForceSyncNow(INVOCATION_REASON_MANUAL);
  FireSchedulerForSync(INVOCATION_REASON_MANUAL);
  clock_.SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds));
  EXPECT_CALL(*this,
              OnSyncFinishedProxy(
                  CryptAuthDeviceManager::SyncResult::FAILURE,
                  CryptAuthDeviceManager::DeviceChangeResult::UNCHANGED));
  error_callback_.Run(NetworkRequestError::kEndpointNotFound);
  EXPECT_EQ(old_sync_time, device_manager_->GetLastSyncTime());
  EXPECT_TRUE(pref_service_.GetBoolean(
      prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure));
  EXPECT_EQ(static_cast<int>(INVOCATION_REASON_MANUAL),
            pref_service_.GetInteger(prefs::kCryptAuthDeviceSyncReason));

  // The second recovery sync succeeds.
  ON_CALL(*sync_scheduler(), GetStrategy())
      .WillByDefault(Return(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY));
  FireSchedulerForSync(INVOCATION_REASON_MANUAL);
  clock_.SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds + 30));
  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
  success_callback_.Run(get_my_devices_response_);
  EXPECT_EQ(clock_.Now(), device_manager_->GetLastSyncTime());

  ExpectSyncedDevicesAndPrefAreEqual(
      devices_in_response_, device_manager_->GetSyncedDevices(), pref_service_);

  EXPECT_FLOAT_EQ(
      clock_.Now().ToDoubleT(),
      pref_service_.GetDouble(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds));
  EXPECT_EQ(static_cast<int>(INVOCATION_REASON_UNKNOWN),
            pref_service_.GetInteger(prefs::kCryptAuthDeviceSyncReason));
  EXPECT_FALSE(pref_service_.GetBoolean(
      prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure));
}

TEST_F(CryptAuthDeviceManagerImplTest, PeriodicSyncFailsThenSucceeds) {
  device_manager_->Start();
  base::Time old_sync_time = device_manager_->GetLastSyncTime();

  // The first periodic sync fails.
  FireSchedulerForSync(INVOCATION_REASON_PERIODIC);
  clock_.SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds));
  EXPECT_CALL(*this,
              OnSyncFinishedProxy(
                  CryptAuthDeviceManager::SyncResult::FAILURE,
                  CryptAuthDeviceManager::DeviceChangeResult::UNCHANGED));
  error_callback_.Run(NetworkRequestError::kAuthenticationError);
  EXPECT_EQ(old_sync_time, device_manager_->GetLastSyncTime());
  EXPECT_TRUE(pref_service_.GetBoolean(
      prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure));

  // The second recovery sync succeeds.
  ON_CALL(*sync_scheduler(), GetStrategy())
      .WillByDefault(Return(SyncScheduler::Strategy::AGGRESSIVE_RECOVERY));
  FireSchedulerForSync(INVOCATION_REASON_FAILURE_RECOVERY);
  clock_.SetNow(base::Time::FromDoubleT(kLaterTimeNowSeconds + 30));
  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
  success_callback_.Run(get_my_devices_response_);
  EXPECT_EQ(clock_.Now(), device_manager_->GetLastSyncTime());

  ExpectSyncedDevicesAndPrefAreEqual(
      devices_in_response_, device_manager_->GetSyncedDevices(), pref_service_);

  EXPECT_FLOAT_EQ(
      clock_.Now().ToDoubleT(),
      pref_service_.GetDouble(prefs::kCryptAuthDeviceSyncLastSyncTimeSeconds));
  EXPECT_FALSE(pref_service_.GetBoolean(
      prefs::kCryptAuthDeviceSyncIsRecoveringFromFailure));
}

TEST_F(CryptAuthDeviceManagerImplTest, SyncSameDevice) {
  device_manager_->Start();
  auto original_devices = device_manager_->GetSyncedDevices();

  // Sync new devices.
  FireSchedulerForSync(INVOCATION_REASON_PERIODIC);
  ASSERT_FALSE(success_callback_.is_null());
  EXPECT_CALL(*this,
              OnSyncFinishedProxy(
                  CryptAuthDeviceManager::SyncResult::SUCCESS,
                  CryptAuthDeviceManager::DeviceChangeResult::UNCHANGED));

  // Sync the same device.
  ExternalDeviceInfo synced_device;
  synced_device.set_public_key(kStoredPublicKey);
  synced_device.set_friendly_device_name(kStoredDeviceName);
  synced_device.set_bluetooth_address(kStoredBluetoothAddress);
  synced_device.set_unlockable(kStoredUnlockable);
  GetMyDevicesResponse get_my_devices_response;
  get_my_devices_response.add_devices()->CopyFrom(synced_device);
  success_callback_.Run(get_my_devices_response);

  // Check that devices are still the same after sync.
  ExpectSyncedDevicesAndPrefAreEqual(
      original_devices, device_manager_->GetSyncedDevices(), pref_service_);
}

TEST_F(CryptAuthDeviceManagerImplTest, SyncEmptyDeviceList) {
  GetMyDevicesResponse empty_response;

  device_manager_->Start();
  EXPECT_EQ(1u, device_manager_->GetSyncedDevices().size());

  FireSchedulerForSync(INVOCATION_REASON_PERIODIC);
  ASSERT_FALSE(success_callback_.is_null());
  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
  success_callback_.Run(empty_response);

  ExpectSyncedDevicesAndPrefAreEqual(std::vector<ExternalDeviceInfo>(),
                                     device_manager_->GetSyncedDevices(),
                                     pref_service_);
}

TEST_F(CryptAuthDeviceManagerImplTest, SyncThreeDevices) {
  GetMyDevicesResponse response(get_my_devices_response_);
  ExternalDeviceInfo synced_device2;
  synced_device2.set_public_key("new public key");
  synced_device2.set_friendly_device_name("new device name");
  synced_device2.set_bluetooth_address("aa:bb:cc:dd:ee:ff");
  synced_device2.add_supported_software_features(
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST));
  synced_device2.add_enabled_software_features(
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST));

  response.add_devices()->CopyFrom(synced_device2);

  std::vector<ExternalDeviceInfo> expected_devices;
  expected_devices.push_back(devices_in_response_[0]);
  expected_devices.push_back(devices_in_response_[1]);
  expected_devices.push_back(synced_device2);

  device_manager_->Start();
  EXPECT_EQ(1u, device_manager_->GetSyncedDevices().size());
  EXPECT_EQ(
      1u,
      pref_service_.GetList(prefs::kCryptAuthDeviceSyncUnlockKeys)->GetSize());

  FireSchedulerForSync(INVOCATION_REASON_PERIODIC);
  ASSERT_FALSE(success_callback_.is_null());
  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
  success_callback_.Run(response);

  ExpectSyncedDevicesAndPrefAreEqual(
      expected_devices, device_manager_->GetSyncedDevices(), pref_service_);
}

TEST_F(CryptAuthDeviceManagerImplTest, SyncOnGCMPushMessage) {
  device_manager_->Start();

  EXPECT_CALL(*sync_scheduler(), ForceSync());
  gcm_manager_.PushResyncMessage();

  FireSchedulerForSync(INVOCATION_REASON_SERVER_INITIATED);

  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
  success_callback_.Run(get_my_devices_response_);

  ExpectSyncedDevicesAndPrefAreEqual(
      devices_in_response_, device_manager_->GetSyncedDevices(), pref_service_);
}

TEST_F(CryptAuthDeviceManagerImplTest, SyncDeviceWithNoContents) {
  device_manager_->Start();

  EXPECT_CALL(*sync_scheduler(), ForceSync());
  gcm_manager_.PushResyncMessage();

  FireSchedulerForSync(INVOCATION_REASON_SERVER_INITIATED);

  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
  success_callback_.Run(get_my_devices_response_);

  ExpectSyncedDevicesAndPrefAreEqual(
      devices_in_response_, device_manager_->GetSyncedDevices(), pref_service_);
}

TEST_F(CryptAuthDeviceManagerImplTest, SyncFullyDetailedExternalDeviceInfos) {
  // First, use a device with only a public key (a public key is the only
  // required field). This ensures devices work properly when they do not have
  // all fields filled out.
  ExternalDeviceInfo device_with_only_public_key;
  device_with_only_public_key.set_public_key("publicKey1");
  device_with_only_public_key.add_supported_software_features(
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST));
  device_with_only_public_key.add_enabled_software_features(
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST));

  // Second, use a device with all fields filled out. This ensures that all
  // device details are properly saved.
  ExternalDeviceInfo device_with_all_fields;
  device_with_all_fields.set_public_key("publicKey2");
  device_with_all_fields.set_friendly_device_name("deviceName");
  device_with_all_fields.set_bluetooth_address("aa:bb:cc:dd:ee:ff");
  device_with_all_fields.set_unlockable(true);
  device_with_all_fields.set_last_update_time_millis(123456789L);
  device_with_all_fields.set_device_type(DeviceType::ANDROIDOS);

  BeaconSeed seed1;
  seed1.set_data(kBeaconSeed1Data);
  seed1.set_start_time_millis(kBeaconSeed1StartTime);
  seed1.set_end_time_millis(kBeaconSeed1EndTime);
  device_with_all_fields.add_beacon_seeds()->CopyFrom(seed1);

  BeaconSeed seed2;
  seed2.set_data(kBeaconSeed2Data);
  seed2.set_start_time_millis(kBeaconSeed2StartTime);
  seed2.set_end_time_millis(kBeaconSeed2EndTime);
  device_with_all_fields.add_beacon_seeds()->CopyFrom(seed2);

  device_with_all_fields.set_arc_plus_plus(true);
  device_with_all_fields.set_pixel_phone(true);

  device_with_all_fields.add_supported_software_features(
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST));
  device_with_all_fields.add_supported_software_features(
      SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_HOST));

  device_with_all_fields.add_enabled_software_features(
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST));

  std::vector<ExternalDeviceInfo> expected_devices;
  expected_devices.push_back(device_with_only_public_key);
  expected_devices.push_back(device_with_all_fields);

  device_manager_->Start();
  FireSchedulerForSync(INVOCATION_REASON_PERIODIC);
  ASSERT_FALSE(success_callback_.is_null());
  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));

  GetMyDevicesResponse response;
  response.add_devices()->CopyFrom(device_with_only_public_key);
  response.add_devices()->CopyFrom(device_with_all_fields);
  success_callback_.Run(response);

  ExpectSyncedDevicesAndPrefAreEqual(
      expected_devices, device_manager_->GetSyncedDevices(), pref_service_);
}

TEST_F(CryptAuthDeviceManagerImplTest, SubsetsOfSyncedDevices) {
  device_manager_->Start();

  FireSchedulerForSync(INVOCATION_REASON_PERIODIC);
  ASSERT_FALSE(success_callback_.is_null());
  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
  success_callback_.Run(get_my_devices_response_);

  // All synced devices.
  ExpectSyncedDevicesAndPrefAreEqual(
      devices_in_response_, device_manager_->GetSyncedDevices(), pref_service_);

  // Only unlock keys.
  ExpectSyncedDevicesAreEqual(
      std::vector<ExternalDeviceInfo>(1, devices_in_response_[0]),
      device_manager_->GetUnlockKeys());

  // Only tether hosts.
  ExpectSyncedDevicesAreEqual(
      std::vector<ExternalDeviceInfo>(1, devices_in_response_[1]),
      device_manager_->GetTetherHosts());
}

TEST_F(CryptAuthDeviceManagerImplTest,
       TestDeprecatedBooleansArePersistedOnlyAsSoftwareFeatures) {
  device_manager_->Start();

  ExternalDeviceInfo device;
  device.set_public_key("public key");
  device.set_friendly_device_name("deprecated device");
  device.set_unlock_key(true);
  device.set_mobile_hotspot_supported(true);

  devices_in_response_.push_back(device);
  get_my_devices_response_.add_devices()->CopyFrom(device);

  FireSchedulerForSync(INVOCATION_REASON_PERIODIC);
  ASSERT_FALSE(success_callback_.is_null());
  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
  success_callback_.Run(get_my_devices_response_);

  ExternalDeviceInfo synced_device = device_manager_->GetSyncedDevices()[2];

  EXPECT_FALSE(synced_device.unlock_key());
  EXPECT_FALSE(synced_device.mobile_hotspot_supported());

  EXPECT_TRUE(base::ContainsValue(
      synced_device.supported_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST)));
  EXPECT_TRUE(base::ContainsValue(
      synced_device.enabled_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST)));
  EXPECT_TRUE(base::ContainsValue(
      synced_device.supported_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_HOST)));
  EXPECT_FALSE(base::ContainsValue(
      synced_device.enabled_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_HOST)));
}

TEST_F(CryptAuthDeviceManagerImplTest,
       TestIgnoreDeprecatedBooleansIfSoftwareFeaturesArePresent) {
  device_manager_->Start();

  ExternalDeviceInfo device;
  device.set_public_key("public key");
  device.set_friendly_device_name("deprecated device");
  device.set_unlock_key(false);
  device.set_mobile_hotspot_supported(false);

  device.add_supported_software_features(
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST));
  device.add_enabled_software_features(
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST));
  device.add_supported_software_features(
      SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_HOST));

  devices_in_response_.push_back(device);
  get_my_devices_response_.add_devices()->CopyFrom(device);

  FireSchedulerForSync(INVOCATION_REASON_PERIODIC);
  ASSERT_FALSE(success_callback_.is_null());
  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
  success_callback_.Run(get_my_devices_response_);

  ExternalDeviceInfo synced_device = device_manager_->GetSyncedDevices()[2];

  EXPECT_FALSE(synced_device.unlock_key());
  EXPECT_FALSE(synced_device.mobile_hotspot_supported());

  EXPECT_TRUE(base::ContainsValue(
      synced_device.supported_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST)));
  EXPECT_TRUE(base::ContainsValue(
      synced_device.enabled_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST)));
  EXPECT_TRUE(base::ContainsValue(
      synced_device.supported_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_HOST)));
  EXPECT_FALSE(base::ContainsValue(
      synced_device.enabled_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_HOST)));
}

// Regression test for crbug.com/888031.
TEST_F(CryptAuthDeviceManagerImplTest,
       TestMigrateFromIntToStringSoftwareFeaturePrefRepresentation) {
  device_manager_->Start();

  ExternalDeviceInfo device;
  device.set_public_key("public key");
  device.set_friendly_device_name("deprecated device");

  // Simulate how older client versions persisted SoftwareFeatures as ints.
  device.add_supported_software_features(
      std::to_string(SoftwareFeature::EASY_UNLOCK_HOST));
  device.add_enabled_software_features(
      std::to_string(SoftwareFeature::EASY_UNLOCK_HOST));
  device.add_supported_software_features(
      std::to_string(SoftwareFeature::MAGIC_TETHER_HOST));

  devices_in_response_.push_back(device);
  get_my_devices_response_.add_devices()->CopyFrom(device);

  FireSchedulerForSync(INVOCATION_REASON_PERIODIC);
  ASSERT_FALSE(success_callback_.is_null());
  EXPECT_CALL(*this, OnSyncFinishedProxy(
                         CryptAuthDeviceManager::SyncResult::SUCCESS,
                         CryptAuthDeviceManager::DeviceChangeResult::CHANGED));
  success_callback_.Run(get_my_devices_response_);

  ExternalDeviceInfo synced_device = device_manager_->GetSyncedDevices()[2];

  // CryptAuthDeviceManager should recognize that the SoftwareFeature prefs had
  // been stored as refs, and convert them to their full string representations.
  EXPECT_TRUE(base::ContainsValue(
      synced_device.supported_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST)));
  EXPECT_TRUE(base::ContainsValue(
      synced_device.enabled_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::EASY_UNLOCK_HOST)));
  EXPECT_TRUE(base::ContainsValue(
      synced_device.supported_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_HOST)));
  EXPECT_FALSE(base::ContainsValue(
      synced_device.enabled_software_features(),
      SoftwareFeatureEnumToString(SoftwareFeature::MAGIC_TETHER_HOST)));
}

}  // namespace cryptauth
