// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/browser_sync/profile_sync_service.h"

#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "components/browser_sync/profile_sync_test_util.h"
#include "components/prefs/pref_service.h"
#include "components/sync/base/pref_names.h"
#include "components/sync/driver/data_type_manager_mock.h"
#include "components/sync/driver/fake_data_type_controller.h"
#include "components/sync/driver/sync_api_component_factory_mock.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/engine/fake_sync_engine.h"
#include "components/sync/engine/mock_sync_engine.h"
#include "services/identity/public/cpp/identity_test_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using syncer::DataTypeManager;
using syncer::DataTypeManagerMock;
using syncer::FakeSyncEngine;
using syncer::MockSyncEngine;
using testing::_;
using testing::ByMove;
using testing::DoAll;
using testing::InvokeWithoutArgs;
using testing::Mock;
using testing::NiceMock;
using testing::Return;

namespace browser_sync {

namespace {

const char kEmail[] = "test_user@gmail.com";

void SetError(DataTypeManager::ConfigureResult* result) {
  syncer::DataTypeStatusTable::TypeErrorMap errors;
  errors[syncer::BOOKMARKS] =
      syncer::SyncError(FROM_HERE, syncer::SyncError::UNRECOVERABLE_ERROR,
                        "Error", syncer::BOOKMARKS);
  result->data_type_status_table.UpdateFailedDataTypes(errors);
}

}  // namespace

ACTION_P(InvokeOnConfigureStart, sync_service) {
  sync_service->OnConfigureStart();
}

ACTION_P3(InvokeOnConfigureDone, sync_service, error_callback, result) {
  DataTypeManager::ConfigureResult configure_result =
      static_cast<DataTypeManager::ConfigureResult>(result);
  if (result.status == syncer::DataTypeManager::ABORTED)
    error_callback.Run(&configure_result);
  sync_service->OnConfigureDone(configure_result);
}

class ProfileSyncServiceStartupTest : public testing::Test {
 public:
  ProfileSyncServiceStartupTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME),
        sync_prefs_(profile_sync_service_bundle_.pref_service()) {
    profile_sync_service_bundle_.identity_test_env()
        ->SetAutomaticIssueOfAccessTokens(true);
  }

  ~ProfileSyncServiceStartupTest() override {
    sync_service_->Shutdown();
  }

  void CreateSyncService(ProfileSyncService::StartBehavior start_behavior,
                         syncer::ModelTypeSet registered_types =
                             syncer::ModelTypeSet(syncer::BOOKMARKS)) {
    ProfileSyncServiceBundle::SyncClientBuilder builder(
        &profile_sync_service_bundle_);
    ProfileSyncService::InitParams init_params =
        profile_sync_service_bundle_.CreateBasicInitParams(start_behavior,
                                                           builder.Build());

    ON_CALL(*component_factory(), CreateCommonDataTypeControllers(_))
        .WillByDefault(InvokeWithoutArgs([=]() {
          syncer::DataTypeController::TypeVector controllers;
          for (syncer::ModelType type : registered_types) {
            controllers.push_back(
                std::make_unique<syncer::FakeDataTypeController>(type));
          }
          return controllers;
        }));

    sync_service_ =
        std::make_unique<ProfileSyncService>(std::move(init_params));
  }

  void SimulateTestUserSignin() {
    profile_sync_service_bundle_.identity_test_env()
        ->MakePrimaryAccountAvailable(kEmail);
  }

  void SimulateTestUserSigninWithoutRefreshToken() {
    // Set the primary account *without* providing an OAuth token.
    profile_sync_service_bundle_.identity_test_env()->SetPrimaryAccount(kEmail);
  }

  void UpdateCredentials() {
    profile_sync_service_bundle_.identity_test_env()
        ->SetRefreshTokenForPrimaryAccount();
  }

  DataTypeManagerMock* SetUpDataTypeManagerMock() {
    auto data_type_manager = std::make_unique<NiceMock<DataTypeManagerMock>>();
    DataTypeManagerMock* data_type_manager_raw = data_type_manager.get();
    ON_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
        .WillByDefault(Return(ByMove(std::move(data_type_manager))));
    return data_type_manager_raw;
  }

  FakeSyncEngine* SetUpFakeSyncEngine() {
    auto sync_engine = std::make_unique<FakeSyncEngine>();
    FakeSyncEngine* sync_engine_raw = sync_engine.get();
    ON_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
        .WillByDefault(Return(ByMove(std::move(sync_engine))));
    return sync_engine_raw;
  }

  MockSyncEngine* SetUpMockSyncEngine() {
    auto sync_engine = std::make_unique<NiceMock<MockSyncEngine>>();
    MockSyncEngine* sync_engine_raw = sync_engine.get();
    ON_CALL(*component_factory(), CreateSyncEngine(_, _, _, _))
        .WillByDefault(Return(ByMove(std::move(sync_engine))));
    return sync_engine_raw;
  }

  syncer::SyncPrefs* sync_prefs() { return &sync_prefs_; }

  ProfileSyncService* sync_service() { return sync_service_.get(); }

  PrefService* pref_service() {
    return profile_sync_service_bundle_.pref_service();
  }

  syncer::SyncApiComponentFactoryMock* component_factory() {
    return profile_sync_service_bundle_.component_factory();
  }

  void FastForwardUntilNoTasksRemain() {
    scoped_task_environment_.FastForwardUntilNoTasksRemain();
  }

 private:
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  ProfileSyncServiceBundle profile_sync_service_bundle_;
  syncer::SyncPrefs sync_prefs_;
  std::unique_ptr<ProfileSyncService> sync_service_;
};

class ProfileSyncServiceWithStandaloneTransportStartupTest
    : public ProfileSyncServiceStartupTest {
 protected:
  ProfileSyncServiceWithStandaloneTransportStartupTest() {
    feature_list_.InitAndEnableFeature(switches::kSyncStandaloneTransport);
  }

  ~ProfileSyncServiceWithStandaloneTransportStartupTest() override {}

 private:
  base::test::ScopedFeatureList feature_list_;
};

class ProfileSyncServiceWithoutStandaloneTransportStartupTest
    : public ProfileSyncServiceStartupTest {
 protected:
  ProfileSyncServiceWithoutStandaloneTransportStartupTest() {
    feature_list_.InitAndDisableFeature(switches::kSyncStandaloneTransport);
  }

  ~ProfileSyncServiceWithoutStandaloneTransportStartupTest() override {}

 private:
  base::test::ScopedFeatureList feature_list_;
};

// ChromeOS does not support sign-in after startup (in particular,
// IdentityManager::Observer::OnPrimaryAccountSet never gets called).
#if !defined(OS_CHROMEOS)
TEST_F(ProfileSyncServiceWithoutStandaloneTransportStartupTest,
       StartFirstTime) {
  // We've never completed startup.
  ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());

  CreateSyncService(ProfileSyncService::MANUAL_START);
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0);
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::STOPPED));

  // Should not actually start, rather just clean things up and wait
  // to be enabled.
  sync_service()->Initialize();
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
            sync_service()->GetTransportState());

  // Preferences should be back to defaults.
  EXPECT_EQ(base::Time(), sync_prefs()->GetLastSyncedTime());
  EXPECT_FALSE(sync_prefs()->IsFirstSetupComplete());

  // This tells the ProfileSyncService that setup is now in progress, which
  // causes it to try starting up the engine. We're not signed in yet though, so
  // that won't work.
  auto sync_blocker = sync_service()->GetSetupInProgressHandle();
  EXPECT_FALSE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
            sync_service()->GetTransportState());

  // Simulate successful signin. This will cause ProfileSyncService to start,
  // since all conditions are now fulfilled.
  SimulateTestUserSignin();

  // Now we're signed in, so the engine can start. There's already a setup in
  // progress, so we don't go into the WAITING_FOR_START_REQUEST state. Engine
  // initialization is immediate in this test, so we also bypass the
  // INITIALIZING state.
  EXPECT_TRUE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
            sync_service()->GetTransportState());

  // Simulate the UI telling sync it has finished setting up. Note that this is
  // a two-step process: Releasing the SetupInProgressHandle, and marking first
  // setup complete.
  sync_blocker.reset();
  // Now setup isn't in progress anymore, but Sync is still waiting to be told
  // that the initial setup was completed.
  ASSERT_FALSE(sync_service()->IsSetupInProgress());
  EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
            sync_service()->GetTransportState());

  // Marking first setup complete will let ProfileSyncService configure the
  // DataTypeManager.
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  sync_service()->GetUserSettings()->SetFirstSetupComplete();

  // This should have fully enabled sync.
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());
  EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_TRUE(sync_service()->IsSyncFeatureActive());

  EXPECT_CALL(*data_type_manager, Stop(syncer::BROWSER_SHUTDOWN));
}

TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest, StartFirstTime) {
  // We've never completed startup.
  ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());

  CreateSyncService(ProfileSyncService::MANUAL_START);
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0);
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::STOPPED));

  // Should not actually start, rather just clean things up and wait
  // to be enabled.
  sync_service()->Initialize();
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
            sync_service()->GetTransportState());

  // Preferences should be back to defaults.
  EXPECT_EQ(base::Time(), sync_prefs()->GetLastSyncedTime());
  EXPECT_FALSE(sync_prefs()->IsFirstSetupComplete());

  // This tells the ProfileSyncService that setup is now in progress, which
  // causes it to try starting up the engine. We're not signed in yet though, so
  // that won't work.
  auto sync_blocker = sync_service()->GetSetupInProgressHandle();
  EXPECT_FALSE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
            sync_service()->GetTransportState());

  SimulateTestUserSignin();

  // Now we're signed in, so the engine can start. There's already a setup in
  // progress, so we don't go into the WAITING_FOR_START_REQUEST state. Engine
  // initialization is immediate in this test, so we also bypass the
  // INITIALIZING state.
  EXPECT_TRUE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
            sync_service()->GetTransportState());

  // Simulate the UI telling sync it has finished setting up. Note that this is
  // a two-step process: Releasing the SetupInProgressHandle, and marking first
  // setup complete.
  // Since standalone transport is enabled, completed first-time setup is not a
  // requirement, so the service will start up as soon as the setup handle is
  // released.
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  sync_blocker.reset();
  ASSERT_FALSE(sync_service()->IsSetupInProgress());
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());
  // Sync-the-feature is still not active, but rather pending confirmation.
  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_FALSE(sync_service()->IsSyncFeatureActive());

  // Marking first setup complete will let ProfileSyncService reconfigure the
  // DataTypeManager in full Sync-the-feature mode.
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  sync_service()->GetUserSettings()->SetFirstSetupComplete();

  // This should have fully enabled sync.
  EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_TRUE(sync_service()->IsSyncFeatureActive());
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());

  EXPECT_CALL(*data_type_manager, Stop(syncer::BROWSER_SHUTDOWN));
}
#endif  // OS_CHROMEOS

TEST_F(ProfileSyncServiceStartupTest, StartNoCredentials) {
  // We're already signed in, but don't have a refresh token.
  SimulateTestUserSigninWithoutRefreshToken();

  CreateSyncService(ProfileSyncService::MANUAL_START);

  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));

  sync_service()->Initialize();

  // ProfileSyncService should now be active, but of course not have an access
  // token.
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());
  EXPECT_TRUE(sync_service()->GetAccessTokenForTest().empty());
  // Note that ProfileSyncService is not in an auth error state - no auth was
  // attempted, so no error.
}

TEST_F(ProfileSyncServiceStartupTest, StartInvalidCredentials) {
  SimulateTestUserSignin();

  CreateSyncService(ProfileSyncService::MANUAL_START);

  sync_service()->GetUserSettings()->SetFirstSetupComplete();

  // Tell the engine to stall while downloading control types (simulating an
  // auth error).
  FakeSyncEngine* fake_engine = SetUpFakeSyncEngine();
  fake_engine->set_fail_initial_download(true);
  // Note: Since engine initialization will fail, the DataTypeManager should not
  // get created at all here.

  sync_service()->Initialize();

  // Engine initialization failures puts the service into an unrecoverable error
  // state. It'll take either a browser restart or a full sign-out+sign-in to
  // get out of this.
  EXPECT_TRUE(sync_service()->HasUnrecoverableError());
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
            sync_service()->GetTransportState());
}

TEST_F(ProfileSyncServiceStartupTest, StartCrosNoCredentials) {
  // We've never completed startup.
  ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());

  // On ChromeOS, the user is always immediately signed in, but a refresh token
  // isn't necessarily available yet.
  SimulateTestUserSigninWithoutRefreshToken();

  CreateSyncService(ProfileSyncService::AUTO_START);

  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();

  // Calling Initialize should cause the service to immediately create and
  // initialize the engine, and configure the DataTypeManager.
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  sync_service()->Initialize();
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));

  // Sync should be considered active, even though there is no refresh token.
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());
  // Since we're in AUTO_START mode, FirstSetupComplete gets set automatically.
  EXPECT_TRUE(sync_service()->GetUserSettings()->IsFirstSetupComplete());
}

TEST_F(ProfileSyncServiceStartupTest, StartCrosFirstTime) {
  // On ChromeOS, the user is always immediately signed in, but a refresh token
  // isn't necessarily available yet.
  SimulateTestUserSigninWithoutRefreshToken();

  CreateSyncService(ProfileSyncService::AUTO_START);

  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));

  // The primary account is already populated, all that's left to do is provide
  // a refresh token.
  UpdateCredentials();
  sync_service()->Initialize();
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());
  EXPECT_CALL(*data_type_manager, Stop(syncer::BROWSER_SHUTDOWN));
}

TEST_F(ProfileSyncServiceStartupTest, StartNormal) {
  // We have previously completed the initial Sync setup, and the user is
  // already signed in.
  sync_prefs()->SetFirstSetupComplete();
  SimulateTestUserSignin();

  CreateSyncService(ProfileSyncService::MANUAL_START);
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));

  // Since all conditions for starting Sync are already fulfilled, calling
  // Initialize should immediately create and initialize the engine and
  // configure the DataTypeManager. In this test, all of these operations are
  // synchronous.
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  sync_service()->Initialize();
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));

  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());

  EXPECT_CALL(*data_type_manager, Stop(syncer::BROWSER_SHUTDOWN));
}

TEST_F(ProfileSyncServiceWithoutStandaloneTransportStartupTest, StopSync) {
  CreateSyncService(ProfileSyncService::MANUAL_START);
  SimulateTestUserSignin();
  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));

  sync_service()->Initialize();

  EXPECT_CALL(*data_type_manager, Stop(syncer::STOP_SYNC));
  sync_service()->GetUserSettings()->SetSyncRequested(false);

  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
}

TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest, StopSync) {
  CreateSyncService(ProfileSyncService::MANUAL_START);
  SimulateTestUserSignin();
  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));

  sync_service()->Initialize();

  EXPECT_CALL(*data_type_manager, Stop(syncer::STOP_SYNC));
  // On SetSyncRequested(false), the sync service will immediately start up
  // again in transport mode.
  SetUpFakeSyncEngine();
  data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  sync_service()->GetUserSettings()->SetSyncRequested(false);

  // Sync-the-feature is still considered off.
  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
}

TEST_F(ProfileSyncServiceWithoutStandaloneTransportStartupTest, DisableSync) {
  CreateSyncService(ProfileSyncService::MANUAL_START);
  SimulateTestUserSignin();
  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));

  sync_service()->Initialize();

  EXPECT_CALL(*data_type_manager, Stop(syncer::DISABLE_SYNC));
  sync_service()->StopAndClear();

  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
}

TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest, DisableSync) {
  CreateSyncService(ProfileSyncService::MANUAL_START);
  SimulateTestUserSignin();
  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));

  sync_service()->Initialize();

  // On StopAndClear(), the sync service will immediately start up again in
  // transport mode.
  SetUpFakeSyncEngine();
  data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  sync_service()->StopAndClear();

  // Sync-the-feature is still considered off.
  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
}

// Test that we can recover from a case where a bug in the code resulted in
// OnUserChoseDatatypes not being properly called and datatype preferences
// therefore being left unset.
TEST_F(ProfileSyncServiceStartupTest, StartRecoverDatatypePrefs) {
  // Clear the datatype preference fields (simulating bug 154940).
  pref_service()->ClearPref(syncer::prefs::kSyncKeepEverythingSynced);
  syncer::ModelTypeSet user_types = syncer::UserTypes();
  for (syncer::ModelType type : user_types) {
    pref_service()->ClearPref(syncer::SyncPrefs::GetPrefNameForDataType(type));
  }

  CreateSyncService(ProfileSyncService::MANUAL_START);
  SimulateTestUserSignin();
  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));

  sync_service()->Initialize();

  EXPECT_TRUE(sync_prefs()->HasKeepEverythingSynced());
}

// Verify that the recovery of datatype preferences doesn't overwrite a valid
// case where only bookmarks are enabled.
TEST_F(ProfileSyncServiceStartupTest, StartDontRecoverDatatypePrefs) {
  // Explicitly set Keep Everything Synced to false and have only bookmarks
  // enabled.
  sync_prefs()->SetKeepEverythingSynced(false);

  CreateSyncService(ProfileSyncService::MANUAL_START);
  SimulateTestUserSignin();
  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));
  sync_service()->Initialize();

  EXPECT_FALSE(sync_prefs()->HasKeepEverythingSynced());
}

TEST_F(ProfileSyncServiceStartupTest, ManagedStartup) {
  // Service should not be started by Initialize() since it's managed.
  SimulateTestUserSignin();
  CreateSyncService(ProfileSyncService::MANUAL_START);

  // Disable sync through policy.
  sync_prefs()->SetManagedForTest(true);

  EXPECT_CALL(*component_factory(), CreateSyncEngine(_, _, _, _)).Times(0);
  EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
      .Times(0);
  sync_service()->Initialize();
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
            sync_service()->GetDisableReasons());
}

TEST_F(ProfileSyncServiceWithoutStandaloneTransportStartupTest, SwitchManaged) {
  CreateSyncService(ProfileSyncService::MANUAL_START);
  SimulateTestUserSignin();
  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));
  sync_service()->Initialize();
  EXPECT_TRUE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());
  EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_TRUE(sync_service()->IsSyncFeatureActive());

  // The service should stop when switching to managed mode.
  Mock::VerifyAndClearExpectations(data_type_manager);
  EXPECT_CALL(*data_type_manager, state())
      .WillOnce(Return(DataTypeManager::CONFIGURED));
  EXPECT_CALL(*data_type_manager, Stop(syncer::DISABLE_SYNC));
  sync_prefs()->SetManagedForTest(true);
  ASSERT_EQ(syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
            sync_service()->GetDisableReasons());
  EXPECT_FALSE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
            sync_service()->GetTransportState());
  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
  // Note that PSS no longer references |data_type_manager| after stopping.

  // When switching back to unmanaged, the state should change but sync should
  // not start automatically because IsFirstSetupComplete() will be false and
  // no setup is in progress.
  // A new DataTypeManager should not be created.
  Mock::VerifyAndClearExpectations(data_type_manager);
  EXPECT_CALL(*component_factory(), CreateDataTypeManager(_, _, _, _, _, _))
      .Times(0);
  sync_prefs()->SetManagedForTest(false);
  ASSERT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
            sync_service()->GetDisableReasons());
  EXPECT_FALSE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::TransportState::WAITING_FOR_START_REQUEST,
            sync_service()->GetTransportState());
  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
}

TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest, SwitchManaged) {
  CreateSyncService(ProfileSyncService::MANUAL_START);
  SimulateTestUserSignin();
  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));
  sync_service()->Initialize();
  EXPECT_TRUE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());
  EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_TRUE(sync_service()->IsSyncFeatureActive());

  // The service should stop when switching to managed mode.
  Mock::VerifyAndClearExpectations(data_type_manager);
  EXPECT_CALL(*data_type_manager, state())
      .WillOnce(Return(DataTypeManager::CONFIGURED));
  EXPECT_CALL(*data_type_manager, Stop(syncer::DISABLE_SYNC));

  sync_prefs()->SetManagedForTest(true);
  ASSERT_EQ(syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY,
            sync_service()->GetDisableReasons());
  EXPECT_FALSE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
            sync_service()->GetTransportState());
  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
  // Note that PSS no longer references |data_type_manager| after stopping.

  // When switching back to unmanaged, Sync-the-transport should start up
  // automatically, which causes (re)creation of SyncEngine and
  // DataTypeManager.
  SetUpFakeSyncEngine();
  Mock::VerifyAndClearExpectations(data_type_manager);
  data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));

  sync_prefs()->SetManagedForTest(false);

  ASSERT_EQ(syncer::SyncService::DISABLE_REASON_NONE,
            sync_service()->GetDisableReasons());

  EXPECT_TRUE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());
  // Sync-the-feature is still considered off.
  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());
  EXPECT_FALSE(sync_service()->IsSyncFeatureActive());
}

TEST_F(ProfileSyncServiceStartupTest, StartFailure) {
  CreateSyncService(ProfileSyncService::MANUAL_START);
  SimulateTestUserSignin();
  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  SetUpFakeSyncEngine();
  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  DataTypeManager::ConfigureStatus status = DataTypeManager::ABORTED;
  DataTypeManager::ConfigureResult result(status, syncer::ModelTypeSet());
  EXPECT_CALL(*data_type_manager, Configure(_, _))
      .WillRepeatedly(
          DoAll(InvokeOnConfigureStart(sync_service()),
                InvokeOnConfigureDone(sync_service(),
                                      base::BindRepeating(&SetError), result)));
  EXPECT_CALL(*data_type_manager, state())
      .WillOnce(Return(DataTypeManager::STOPPED));
  ON_CALL(*data_type_manager, IsNigoriEnabled()).WillByDefault(Return(true));
  sync_service()->Initialize();
  EXPECT_TRUE(sync_service()->HasUnrecoverableError());
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR,
            sync_service()->GetDisableReasons());
}

TEST_F(ProfileSyncServiceStartupTest, StartDownloadFailed) {
  CreateSyncService(ProfileSyncService::MANUAL_START);
  SimulateTestUserSignin();
  FakeSyncEngine* fake_engine = SetUpFakeSyncEngine();
  fake_engine->set_fail_initial_download(true);

  ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());

  sync_service()->Initialize();

  auto sync_blocker = sync_service()->GetSetupInProgressHandle();
  sync_blocker.reset();
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
            sync_service()->GetTransportState());
}

// ChromeOS does not support sign-in after startup (in particular,
// IdentityManager::Observer::OnPrimaryAccountSet never gets called).
#if !defined(OS_CHROMEOS)
TEST_F(ProfileSyncServiceWithoutStandaloneTransportStartupTest,
       FullStartupSequenceFirstTime) {
  // We've never completed startup.
  ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());

  MockSyncEngine* sync_engine = SetUpMockSyncEngine();
  EXPECT_CALL(*sync_engine, Initialize(_)).Times(0);

  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0);
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::STOPPED));

  // Note: Deferred startup is only enabled if SESSIONS is among the preferred
  // data types.
  CreateSyncService(ProfileSyncService::MANUAL_START,
                    syncer::ModelTypeSet(syncer::SESSIONS));
  sync_service()->Initialize();

  // There is no signed-in user, but nothing else prevents Sync from starting.
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
            sync_service()->GetTransportState());

  // Sign in. Now Sync is ready to start, just waiting for a prod.
  SimulateTestUserSignin();
  EXPECT_EQ(syncer::SyncService::TransportState::WAITING_FOR_START_REQUEST,
            sync_service()->GetTransportState());

  // Once we give the service a prod by initiating Sync setup, it'll start and
  // initialize the engine. Since this is the initial Sync start, this will not
  // be deferred.
  EXPECT_CALL(*sync_engine, Initialize(_));
  auto setup_in_progress_handle = sync_service()->GetSetupInProgressHandle();
  EXPECT_EQ(syncer::SyncService::TransportState::INITIALIZING,
            sync_service()->GetTransportState());

  // Once the engine calls back and says it's initialized, we're just waiting
  // for the user to finish the initial configuration (choosing data types etc.)
  // before actually syncing data.
  sync_service()->OnEngineInitialized(
      syncer::ModelTypeSet(), syncer::WeakHandle<syncer::JsBackend>(),
      syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(), "test-guid",
      "test-session-name", /*success=*/true);
  ASSERT_TRUE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
            sync_service()->GetTransportState());
  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());

  // Once the user finishes the initial setup, the service can actually start
  // configuring the data types. Just marking the initial setup as complete
  // isn't enough though, because setup is still considered in progress (we
  // haven't released the setup-in-progress handle).
  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
            sync_service()->GetTransportState());
  EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());

  // Releasing the setup in progress handle lets the service actually configure
  // the DataTypeManager.
  EXPECT_CALL(*data_type_manager, Configure(_, _))
      .WillOnce(InvokeWithoutArgs(sync_service(),
                                  &ProfileSyncService::OnConfigureStart));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURING));
  setup_in_progress_handle.reset();
  // While DataTypeManager configuration is ongoing, the overall state is still
  // CONFIGURING.
  EXPECT_EQ(syncer::SyncService::TransportState::CONFIGURING,
            sync_service()->GetTransportState());
  EXPECT_TRUE(sync_service()->IsSyncFeatureActive());

  // Finally, once the DataTypeManager says it's done with configuration, Sync
  // is actually fully up and running.
  DataTypeManager::ConfigureResult configure_result(
      DataTypeManager::OK, syncer::ModelTypeSet(syncer::SESSIONS));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  sync_service()->OnConfigureDone(configure_result);
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());
  EXPECT_TRUE(sync_service()->IsSyncFeatureActive());
}

TEST_F(ProfileSyncServiceWithStandaloneTransportStartupTest,
       FullStartupSequenceFirstTime) {
  // We've never completed startup.
  ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());

  MockSyncEngine* sync_engine = SetUpMockSyncEngine();
  EXPECT_CALL(*sync_engine, Initialize(_)).Times(0);

  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0);
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::STOPPED));

  // Note: Deferred startup is only enabled if SESSIONS is among the preferred
  // data types.
  CreateSyncService(ProfileSyncService::MANUAL_START,
                    syncer::ModelTypeSet(syncer::SESSIONS));
  sync_service()->Initialize();

  // There is no signed-in user, but nothing else prevents Sync from starting.
  EXPECT_EQ(syncer::SyncService::DISABLE_REASON_NOT_SIGNED_IN,
            sync_service()->GetDisableReasons());
  EXPECT_EQ(syncer::SyncService::TransportState::DISABLED,
            sync_service()->GetTransportState());

  // Sign in. Now Sync is ready to start, just waiting for a prod.
  SimulateTestUserSignin();
  EXPECT_EQ(syncer::SyncService::TransportState::START_DEFERRED,
            sync_service()->GetTransportState());

  // Once we give the service a prod by initiating Sync setup, it'll start and
  // initialize the engine. Since this is the initial Sync start, this will not
  // be deferred.
  EXPECT_CALL(*sync_engine, Initialize(_));
  auto setup_in_progress_handle = sync_service()->GetSetupInProgressHandle();
  EXPECT_EQ(syncer::SyncService::TransportState::INITIALIZING,
            sync_service()->GetTransportState());

  // Once the engine calls back and says it's initialized, we're just waiting
  // for the user to finish the initial configuration (choosing data types etc.)
  // before actually syncing data.
  sync_service()->OnEngineInitialized(
      syncer::ModelTypeSet(), syncer::WeakHandle<syncer::JsBackend>(),
      syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(), "test-guid",
      "test-session-name", /*success=*/true);
  ASSERT_TRUE(sync_service()->IsEngineInitialized());
  EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
            sync_service()->GetTransportState());
  EXPECT_FALSE(sync_service()->IsSyncFeatureEnabled());

  // Once the user finishes the initial setup, the service can actually start
  // configuring the data types. Just marking the initial setup as complete
  // isn't enough though, because setup is still considered in progress (we
  // haven't released the setup-in-progress handle).
  sync_service()->GetUserSettings()->SetFirstSetupComplete();
  EXPECT_EQ(syncer::SyncService::TransportState::PENDING_DESIRED_CONFIGURATION,
            sync_service()->GetTransportState());
  EXPECT_TRUE(sync_service()->IsSyncFeatureEnabled());

  // Releasing the setup in progress handle lets the service actually configure
  // the DataTypeManager.
  EXPECT_CALL(*data_type_manager, Configure(_, _))
      .WillOnce(InvokeWithoutArgs(sync_service(),
                                  &ProfileSyncService::OnConfigureStart));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURING));
  setup_in_progress_handle.reset();
  // While DataTypeManager configuration is ongoing, the overall state is still
  // CONFIGURING.
  EXPECT_EQ(syncer::SyncService::TransportState::CONFIGURING,
            sync_service()->GetTransportState());
  EXPECT_TRUE(sync_service()->IsSyncFeatureActive());

  // Finally, once the DataTypeManager says it's done with configuration, Sync
  // is actually fully up and running.
  DataTypeManager::ConfigureResult configure_result(
      DataTypeManager::OK, syncer::ModelTypeSet(syncer::SESSIONS));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  sync_service()->OnConfigureDone(configure_result);
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());
  EXPECT_TRUE(sync_service()->IsSyncFeatureActive());
}
#endif  // OS_CHROMEOS

TEST_F(ProfileSyncServiceStartupTest, FullStartupSequenceNthTime) {
  // The user is already signed in and has completed Sync setup before.
  SimulateTestUserSignin();
  sync_prefs()->SetFirstSetupComplete();

  MockSyncEngine* sync_engine = SetUpMockSyncEngine();
  EXPECT_CALL(*sync_engine, Initialize(_)).Times(0);

  DataTypeManagerMock* data_type_manager = SetUpDataTypeManagerMock();
  EXPECT_CALL(*data_type_manager, Configure(_, _)).Times(0);
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::STOPPED));

  // Note: Deferred startup is only enabled if SESSIONS is among the preferred
  // data types.
  CreateSyncService(ProfileSyncService::MANUAL_START,
                    syncer::ModelTypeSet(syncer::SESSIONS));
  sync_service()->Initialize();

  // Nothing is preventing Sync from starting, but it should be deferred so as
  // to now slow down browser startup.
  EXPECT_EQ(syncer::SyncService::TransportState::START_DEFERRED,
            sync_service()->GetTransportState());

  // Wait for the deferred startup timer to expire. The Sync service will start
  // and initialize the engine.
  EXPECT_CALL(*sync_engine, Initialize(_));
  FastForwardUntilNoTasksRemain();
  EXPECT_EQ(syncer::SyncService::TransportState::INITIALIZING,
            sync_service()->GetTransportState());

  // Once the engine calls back and says it's initialized, the DataTypeManager
  // will get configured, since initial setup is already done.
  EXPECT_CALL(*data_type_manager, Configure(_, _));
  sync_service()->OnEngineInitialized(
      syncer::ModelTypeSet(), syncer::WeakHandle<syncer::JsBackend>(),
      syncer::WeakHandle<syncer::DataTypeDebugInfoListener>(), "test-guid",
      "test-session-name", /*success=*/true);
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURING));
  EXPECT_EQ(syncer::SyncService::TransportState::CONFIGURING,
            sync_service()->GetTransportState());

  // Finally, once the DataTypeManager says it's done with configuration, Sync
  // is actually fully up and running.
  DataTypeManager::ConfigureResult configure_result(
      DataTypeManager::OK, syncer::ModelTypeSet(syncer::SESSIONS));
  ON_CALL(*data_type_manager, state())
      .WillByDefault(Return(DataTypeManager::CONFIGURED));
  sync_service()->OnConfigureDone(configure_result);
  EXPECT_EQ(syncer::SyncService::TransportState::ACTIVE,
            sync_service()->GetTransportState());
}

}  // namespace browser_sync
