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

#include "chrome/browser/profiles/profile_manager.h"

#include <stddef.h>

#include <sstream>
#include <string>
#include <utility>

#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/files/file_path_watcher.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/values.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_features.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/delete_profile_helper.h"
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
#include "chrome/browser/profiles/nuke_profile_directory_utils.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_attributes_init_params.h"
#include "chrome/browser/profiles/profile_attributes_storage.h"
#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "chrome/test/base/fake_profile_manager.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "components/account_id/account_id.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "components/prefs/testing_pref_service.h"
#include "components/supervised_user/core/common/pref_names.h"
#include "components/supervised_user/core/common/supervised_user_constants.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_utils.h"
#include "google_apis/gaia/gaia_id.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"

#if !BUILDFLAG(IS_ANDROID)
#include "chrome/browser/lifetime/application_lifetime_desktop.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/test_browser_window.h"
#endif

#if BUILDFLAG(IS_CHROMEOS)
#include "ash/constants/ash_switches.h"
#include "base/check_deref.h"
#include "chrome/browser/ash/login/users/avatar/user_image_manager_impl.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/ash/login/users/user_manager_delegate_impl.h"
#include "chrome/browser/ash/profiles/profile_helper.h"
#include "chrome/browser/ash/settings/scoped_cros_settings_test_helper.h"
#include "chrome/browser/ash/wallpaper_handlers/test_wallpaper_fetcher_delegate.h"
#include "chrome/browser/ui/ash/wallpaper/test_wallpaper_controller.h"
#include "chrome/browser/ui/ash/wallpaper/wallpaper_controller_client_impl.h"
#include "chromeos/ash/components/settings/cros_settings.h"
#include "chromeos/ash/components/system/fake_statistics_provider.h"
#include "chromeos/ash/experiences/arc/arc_features.h"
#include "chromeos/ash/experiences/arc/arc_prefs.h"
#include "chromeos/ash/experiences/arc/session/arc_management_transition.h"
#include "components/user_manager/fake_user_manager.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/test_helper.h"
#include "components/user_manager/user_manager.h"
#include "components/user_manager/user_manager_impl.h"
#include "components/user_manager/user_names.h"
#include "extensions/common/features/feature_session_type.h"
#include "extensions/common/mojom/feature_session_type.mojom.h"
#endif  // BUILDFLAG(IS_CHROMEOS)

using base::ASCIIToUTF16;

namespace {

// This global variable is used to check that value returned to different
// observers is the same.
Profile* g_created_profile = nullptr;

void ExpectNullProfile(base::OnceClosure closure, Profile* profile) {
  EXPECT_EQ(nullptr, profile);
  std::move(closure).Run();
}

void ExpectProfileWithName(const std::string& profile_name,
                           bool incognito,
                           base::OnceClosure closure,
                           Profile* profile) {
  EXPECT_NE(nullptr, profile);
  EXPECT_EQ(incognito, profile->IsOffTheRecord());
  if (incognito)
    profile = profile->GetOriginalProfile();

  // Create a profile on the fly so the the same comparison
  // can be used in Windows and other platforms.
  EXPECT_EQ(base::FilePath().AppendASCII(profile_name), profile->GetBaseName());
  std::move(closure).Run();
}

class ProfileDeletionWaiter {
 public:
  explicit ProfileDeletionWaiter(const Profile* profile)
      : profile_path_(profile->GetPath()) {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  }

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

  void Wait() {
    DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
    DCHECK(!watcher_);
    base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()})
        ->PostTask(FROM_HERE,
                   base::BindOnce(&ProfileDeletionWaiter::StartWatchingPath,
                                  base::Unretained(this)));
    run_loop_.Run();
  }

 private:
  void StartWatchingPath() {
    DCHECK(!watcher_);
    watcher_ = std::make_unique<base::FilePathWatcher>();
    EXPECT_TRUE(watcher_->Watch(
        profile_path_, base::FilePathWatcher::Type::kNonRecursive,
        base::BindRepeating(&ProfileDeletionWaiter::OnChanged,
                            base::Unretained(this))));
    CheckIfPathExists();
  }

  void OnChanged(const base::FilePath& path, bool error) {
    EXPECT_EQ(profile_path_, path);
    EXPECT_FALSE(error);
    CheckIfPathExists();
  }

  void CheckIfPathExists() {
    if (!base::PathExists(profile_path_)) {
      watcher_.reset();
      run_loop_.Quit();
    }
  }

  base::RunLoop run_loop_;
  const base::FilePath profile_path_;
  std::unique_ptr<base::FilePathWatcher> watcher_;
};

}  // namespace

class ProfileManagerTest : public testing::Test {
 public:
  class MockObserver {
   public:
    MOCK_METHOD1(OnProfileInitialized, void(Profile* profile));
    MOCK_METHOD1(OnProfileCreated, void(Profile* profile));
  };

  ProfileManagerTest() = default;

  ProfileManagerTest(const ProfileManagerTest&) = delete;
  ProfileManagerTest& operator=(const ProfileManagerTest&) = delete;
  ~ProfileManagerTest() override = default;

  void SetUp() override {
    // Create a new temporary directory, and store the path
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    TestingBrowserProcess::GetGlobal()->SetProfileManager(
        CreateProfileManagerForTest());

#if BUILDFLAG(IS_CHROMEOS)
    base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kTestType);
    ash::UserImageManagerImpl::SkipDefaultUserImageDownloadForTesting();
    wallpaper_controller_client_ = std::make_unique<
        WallpaperControllerClientImpl>(
        CHECK_DEREF(TestingBrowserProcess::GetGlobal()->local_state()),
        std::make_unique<wallpaper_handlers::TestWallpaperFetcherDelegate>());
    wallpaper_controller_client_->InitForTesting(&test_wallpaper_controller_);

    // Have to manually reset the session type in between test runs because
    // some tests log in users.
    ASSERT_EQ(extensions::mojom::FeatureSessionType::kInitial,
              extensions::GetCurrentFeatureSessionType());
    session_type_ = extensions::ScopedCurrentFeatureSessionType(
        extensions::GetCurrentFeatureSessionType());

    // Initializes ProfileHelper.
    // TODO(crbug.com/40225390): Migrate into BrowserContextHelper.
    ash::ProfileHelper::Get();
#endif
  }

  void TearDown() override {
    TestingBrowserProcess::GetGlobal()->SetProfileManager(nullptr);
    content::RunAllTasksUntilIdle();
#if BUILDFLAG(IS_CHROMEOS)
    session_type_.reset();
    wallpaper_controller_client_.reset();
#endif
  }

 protected:
  virtual std::unique_ptr<ProfileManager> CreateProfileManagerForTest() {
    return std::make_unique<FakeProfileManager>(temp_dir_.GetPath());
  }

  // Helper function to create a profile at `path` for a profile `manager`.
  void CreateProfileAsync(ProfileManager* manager,
                          const base::FilePath& profile_path,
                          MockObserver* mock_observer) {
    manager->CreateProfileAsync(
        profile_path,
        base::BindOnce(&MockObserver::OnProfileInitialized,
                       base::Unretained(mock_observer)),
        base::BindOnce(&MockObserver::OnProfileCreated,
                       base::Unretained(mock_observer)));
  }

#if !BUILDFLAG(IS_ANDROID)
  // Helper function to create a profile with |name| for a profile |manager|.
  void CreateMultiProfileAsync(ProfileManager* manager,
                               const std::string& name,
                               MockObserver* mock_observer) {
    ProfileManager::CreateMultiProfileAsync(
        base::UTF8ToUTF16(name), /*icon_index=*/0, /*is_hidden=*/false,
        base::BindOnce(&MockObserver::OnProfileInitialized,
                       base::Unretained(mock_observer)),
        base::BindOnce(&MockObserver::OnProfileCreated,
                       base::Unretained(mock_observer)));
  }
#endif  // !BUILDFLAG(IS_ANDROID)

  // Helper function to add a profile with |profile_name| to |profile_manager|'s
  // ProfileAttributesStorage, and return the profile created.
  Profile* AddProfileToStorage(ProfileManager* profile_manager,
                               const std::string& path_suffix,
                               const std::u16string& profile_name) {
    ProfileAttributesStorage& storage =
        profile_manager->GetProfileAttributesStorage();
    size_t num_profiles = storage.GetNumberOfProfiles();
    base::FilePath path = temp_dir_.GetPath().AppendASCII(path_suffix);
    ProfileAttributesInitParams params;
    params.profile_path = path;
    params.profile_name = profile_name;
    storage.AddProfile(std::move(params));
    EXPECT_EQ(num_profiles + 1u, storage.GetNumberOfProfiles());
    return profile_manager->GetProfile(path);
  }

  // Helper function to set profile ephemeral at prefs and attributes storage.
  void SetProfileEphemeral(Profile* profile) {
    profile->GetPrefs()->SetBoolean(prefs::kForceEphemeralProfiles, true);

    // Update IsEphemeral in attributes storage, normally it happened via
    // kForceEphemeralProfiles pref change event routed to
    // ProfileImpl::UpdateIsEphemeralInStorage().
    ProfileAttributesStorage& storage =
        g_browser_process->profile_manager()->GetProfileAttributesStorage();
    ProfileAttributesEntry* entry =
        storage.GetProfileAttributesWithPath(profile->GetPath());
    ASSERT_NE(entry, nullptr);
    entry->SetIsEphemeral(true);
  }

#if BUILDFLAG(IS_CHROMEOS)
  // Helper function to register an user with id |user_id| and create profile
  // with a correct path.
  void RegisterUser(const AccountId& account_id) {
    auto* user_manager = user_manager::UserManager::Get();

    // Add user for testing.
    {
      user_manager::TestHelper test_helper(user_manager);
      if (account_id == user_manager::GuestAccountId()) {
        ASSERT_TRUE(test_helper.AddGuestUser());
      } else {
        ASSERT_TRUE(test_helper.AddRegularUser(account_id));
      }
    }

    const std::string user_id_hash =
        user_manager::TestHelper::GetFakeUsernameHash(account_id);
    user_manager::UserManager::Get()->UserLoggedIn(account_id, user_id_hash);
    ash::ProfileHelper* profile_helper = ash::ProfileHelper::Get();
    g_browser_process->profile_manager()->GetProfile(
        profile_helper->GetProfilePathByUserIdHash(user_id_hash));
  }

  std::unique_ptr<Profile> InitProfileForArcTransitionTest(
      bool profile_is_new,
      bool arc_signed_in,
      bool profile_is_child,
      bool user_is_child,
      bool profile_is_managed,
      std::optional<bool> arc_is_managed) {
    ash::ProfileHelper* profile_helper = ash::ProfileHelper::Get();
    user_manager::UserManager* user_manager = user_manager::UserManager::Get();

    const std::string user_email = "user_for_transition@example.com";
    const AccountId account_id =
        AccountId::FromUserEmailGaiaId(user_email, GaiaId("1"));
    const std::string user_id_hash =
        user_manager::TestHelper::GetFakeUsernameHash(account_id);
    const base::FilePath dest_path =
        profile_helper->GetProfilePathByUserIdHash(user_id_hash);

    {
      user_manager::TestHelper test_helper(user_manager);
      if (user_is_child) {
        CHECK(test_helper.AddChildUser(account_id));
      } else {
        CHECK(test_helper.AddRegularUser(account_id));
      }
    }

    TestingProfile::Builder builder;
    builder.SetPath(dest_path);
    builder.SetIsNewProfile(profile_is_new);

    if (profile_is_child)
      builder.SetIsSupervisedProfile();

    builder.OverridePolicyConnectorIsManagedForTesting(profile_is_managed);
    std::unique_ptr<Profile> profile = builder.Build();

    profile->GetPrefs()->SetBoolean(arc::prefs::kArcSignedIn, arc_signed_in);

    if (arc_is_managed.has_value()) {
      profile->GetPrefs()->SetBoolean(arc::prefs::kArcIsManaged,
                                      *arc_is_managed);
    }

    user_manager->UserLoggedIn(account_id, user_id_hash);
    g_browser_process->profile_manager()->InitProfileUserPrefs(profile.get());

    return profile;
  }

  ash::ScopedCrosSettingsTestHelper cros_settings_test_helper_;
#endif

  // The path to temporary directory used to contain the test operations. This
  // comes before |task_environment_| to avoid issues around backend threads
  // still using the temp directories upon teardown.
  base::ScopedTempDir temp_dir_;

  content::BrowserTaskEnvironment task_environment_;

#if BUILDFLAG(IS_CHROMEOS)
  user_manager::ScopedUserManager user_manager_{
      std::make_unique<user_manager::UserManagerImpl>(
          std::make_unique<ash::UserManagerDelegateImpl>(),
          TestingBrowserProcess::GetGlobal()->local_state(),
          ash::CrosSettings::Get())};
  std::unique_ptr<base::AutoReset<extensions::mojom::FeatureSessionType>>
      session_type_;
  std::unique_ptr<WallpaperControllerClientImpl> wallpaper_controller_client_;
  TestWallpaperController test_wallpaper_controller_;
  ash::system::ScopedFakeStatisticsProvider fake_statistics_provider_;
#endif
};

TEST_F(ProfileManagerTest, GetProfile) {
  base::FilePath dest_path = temp_dir_.GetPath();
  dest_path = dest_path.Append(FILE_PATH_LITERAL("New Profile"));

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  // Successfully create a profile.
  Profile* profile = profile_manager->GetProfile(dest_path);
  EXPECT_TRUE(profile);

  // The profile already exists when we call GetProfile. Just load it.
  EXPECT_EQ(profile, profile_manager->GetProfile(dest_path));
}

TEST_F(ProfileManagerTest, DefaultProfileDir) {
  base::FilePath expected_default =
      base::FilePath().AppendASCII(chrome::kInitialProfile);
  EXPECT_EQ(expected_default.value(),
            ProfileManager::GetInitialProfileDir().value());
}

MATCHER(SameNotNull, "The same non-NULL value for all calls.") {
  if (!g_created_profile && arg)
    g_created_profile = arg;
  return arg && arg == g_created_profile;
}

#if BUILDFLAG(IS_CHROMEOS)

// This functionality only exists on Chrome OS.
TEST_F(ProfileManagerTest, LoggedInProfileDir) {
  base::FilePath expected_default =
      base::FilePath().AppendASCII(chrome::kInitialProfile);
  EXPECT_EQ(expected_default.value(),
            ProfileManager::GetInitialProfileDir().value());

  constexpr char kTestUserName[] = "test-user@example.com";
  constexpr GaiaId::Literal kTestUserGaiaId("0123456789");
  const AccountId test_account_id(
      AccountId::FromUserEmailGaiaId(kTestUserName, kTestUserGaiaId));
  auto* user_manager = new ash::FakeChromeUserManager();
  user_manager::ScopedUserManager enabler(base::WrapUnique(user_manager));

  const user_manager::User* active_user =
      user_manager->AddUser(test_account_id);
  user_manager->LoginUser(test_account_id);
  user_manager->SwitchActiveUser(test_account_id);

  base::FilePath expected_logged_in(
      ash::ProfileHelper::GetUserProfileDir(active_user->username_hash()));
  EXPECT_EQ(expected_logged_in.value(),
            ProfileManager::GetInitialProfileDir().value());
  VLOG(1) << temp_dir_.GetPath()
                 .Append(ProfileManager::GetInitialProfileDir())
                 .value();
}

// Test Get[ActiveUser|PrimaryUser|LastUsed]Profile does not load user profile.
TEST_F(ProfileManagerTest, UserProfileLoading) {
  using ::ash::ProfileHelper;

  Profile* const signin_profile = ProfileHelper::GetSigninProfile();

  // Get[Active|Primary|LastUsed]Profile return the sign-in profile before login
  // happens. IsSameOrParent() is used to properly test against TestProfile
  // whose OTR version uses a different temp path.
  EXPECT_TRUE(
      ProfileManager::GetActiveUserProfile()->IsSameOrParent(signin_profile));
  EXPECT_TRUE(
      ProfileManager::GetPrimaryUserProfile()->IsSameOrParent(signin_profile));
  EXPECT_TRUE(
      ProfileManager::GetLastUsedProfile()->IsSameOrParent(signin_profile));

  // User signs in but user profile loading has not started.
  const AccountId account_id = AccountId::FromUserEmailGaiaId(
      "test-user@example.com", GaiaId("0123456789"));
  const std::string user_id_hash =
      user_manager::TestHelper::GetFakeUsernameHash(account_id);
  auto* user_manager = user_manager::UserManager::Get();
  ASSERT_TRUE(
      user_manager::TestHelper(user_manager).AddRegularUser(account_id));
  user_manager->UserLoggedIn(account_id, user_id_hash);

  // Sign-in profile should be returned at this stage. Otherwise, login code
  // ends up in an invalid state. Strange things as in http://crbug.com/728683
  // and http://crbug.com/718734 happens.
  EXPECT_TRUE(
      ProfileManager::GetActiveUserProfile()->IsSameOrParent(signin_profile));
  EXPECT_TRUE(
      ProfileManager::GetPrimaryUserProfile()->IsSameOrParent(signin_profile));

  // GetLastUsedProfile() after login but before a user profile is loaded is
  // fatal.
  EXPECT_DEATH_IF_SUPPORTED(ProfileManager::GetLastUsedProfile(), ".*");

  // Simulate UserSessionManager loads the profile.
  Profile* const user_profile =
      g_browser_process->profile_manager()->GetProfile(
          ProfileHelper::Get()->GetProfilePathByUserIdHash(user_id_hash));
  ASSERT_FALSE(user_profile->IsSameOrParent(signin_profile));

  // User profile is returned thereafter.
  EXPECT_TRUE(
      ProfileManager::GetActiveUserProfile()->IsSameOrParent(user_profile));
  EXPECT_TRUE(
      ProfileManager::GetPrimaryUserProfile()->IsSameOrParent(user_profile));
  EXPECT_TRUE(
      ProfileManager::GetLastUsedProfile()->IsSameOrParent(user_profile));
}

#endif  // BUILDFLAG(IS_CHROMEOS)

TEST_F(ProfileManagerTest, CreateAndUseTwoProfiles) {
  base::FilePath dest_path1 = temp_dir_.GetPath();
  dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1"));

  base::FilePath dest_path2 = temp_dir_.GetPath();
  dest_path2 = dest_path2.Append(FILE_PATH_LITERAL("New Profile 2"));

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  // Successfully create the profiles.
  TestingProfile* profile1 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path1));
  ASSERT_TRUE(profile1);

  TestingProfile* profile2 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path2));
  ASSERT_TRUE(profile2);

  // Access some keyed service to simulate use.
  EXPECT_TRUE(IdentityManagerFactory::GetForProfile(profile1));
  EXPECT_TRUE(IdentityManagerFactory::GetForProfile(profile2));

  // Make sure any pending tasks run before we destroy the profiles.
  content::RunAllTasksUntilIdle();

  TestingBrowserProcess::GetGlobal()->SetProfileManager(nullptr);

  // Make sure backend sequences clean up correctly.
  content::RunAllTasksUntilIdle();
}

TEST_F(ProfileManagerTest, LoadNonExistingProfile) {
  base::FilePath profile_name(FILE_PATH_LITERAL("NonExistingProfile"));
  base::RunLoop run_loop_1;
  base::RunLoop run_loop_2;

  ProfileManager* profile_manager = g_browser_process->profile_manager();
  profile_manager->LoadProfile(
      profile_name, false /* incognito */,
      base::BindOnce(&ExpectNullProfile, run_loop_1.QuitClosure()));
  run_loop_1.Run();

  profile_manager->LoadProfile(
      profile_name, true /* incognito */,
      base::BindOnce(&ExpectNullProfile, run_loop_2.QuitClosure()));
  run_loop_2.Run();
}

TEST_F(ProfileManagerTest, LoadExistingProfile) {
  base::FilePath profile_basename(FILE_PATH_LITERAL("MyProfile"));
  base::FilePath profile_path = temp_dir_.GetPath().Append(profile_basename);
  const base::FilePath other_basename(FILE_PATH_LITERAL("SomeOtherProfile"));
  MockObserver mock_observer1;
  EXPECT_CALL(mock_observer1, OnProfileInitialized(SameNotNull()))
      .Times(testing::AtLeast(1));

  ProfileManager* profile_manager = g_browser_process->profile_manager();
  CreateProfileAsync(profile_manager, profile_path, &mock_observer1);

  // Make sure a real profile is created before continuing.
  content::RunAllTasksUntilIdle();

  base::RunLoop load_profile;
  bool incognito = false;
  profile_manager->LoadProfile(
      profile_basename, incognito,
      base::BindOnce(&ExpectProfileWithName, profile_basename.AsUTF8Unsafe(),
                     incognito, load_profile.QuitClosure()));
  load_profile.Run();

  base::RunLoop load_profile_incognito;
  incognito = true;
  profile_manager->LoadProfile(
      profile_basename, incognito,
      base::BindOnce(&ExpectProfileWithName, profile_basename.AsUTF8Unsafe(),
                     incognito, load_profile_incognito.QuitClosure()));
  load_profile_incognito.Run();

  // Loading some other non existing profile should still return null.
  base::RunLoop load_other_profile;
  profile_manager->LoadProfile(
      other_basename, false,
      base::BindOnce(&ExpectNullProfile, load_other_profile.QuitClosure()));
  load_other_profile.Run();
}

TEST_F(ProfileManagerTest, CreateProfileAsyncMultipleRequests) {
  g_created_profile = nullptr;

  MockObserver mock_observer1;
  EXPECT_CALL(mock_observer1, OnProfileInitialized(SameNotNull()))
      .Times(testing::AtLeast(1));
  MockObserver mock_observer2;
  EXPECT_CALL(mock_observer2, OnProfileInitialized(SameNotNull()))
      .Times(testing::AtLeast(1));
  MockObserver mock_observer3;
  EXPECT_CALL(mock_observer3, OnProfileInitialized(SameNotNull()))
      .Times(testing::AtLeast(1));

  ProfileManager* profile_manager = g_browser_process->profile_manager();
  base::FilePath profile_path = temp_dir_.GetPath().AppendASCII("New Profile");
  CreateProfileAsync(profile_manager, profile_path, &mock_observer1);
  CreateProfileAsync(profile_manager, profile_path, &mock_observer2);
  CreateProfileAsync(profile_manager, profile_path, &mock_observer3);

  content::RunAllTasksUntilIdle();
}

TEST_F(ProfileManagerTest, CreateProfilesAsync) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();

  base::FilePath profile_path1 =
      temp_dir_.GetPath().AppendASCII("New Profile 1");
  base::FilePath profile_path2 =
      temp_dir_.GetPath().AppendASCII("New Profile 2");

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull()))
      .Times(testing::AtLeast(2));
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .Times(testing::AtLeast(2));

  CreateProfileAsync(profile_manager, profile_path1, &mock_observer);
  CreateProfileAsync(profile_manager, profile_path2, &mock_observer);

  content::RunAllTasksUntilIdle();
}

// Regression test for https://crbug.com/1472849
TEST_F(ProfileManagerTest, ConcurrentCreationAsyncAndSync) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::_)).Times(0);
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::_)).Times(0);

  base::FilePath profile_path = temp_dir_.GetPath().AppendASCII("New Profile");
  CreateProfileAsync(profile_manager, profile_path, &mock_observer);

  // The profile is being created, but creation is not complete.
  EXPECT_EQ(nullptr, profile_manager->GetProfileByPath(profile_path));

  // Request synchronous creation of the same profile, this should not crash.
  Profile* profile_created = nullptr;
  Profile* profile_initialized = nullptr;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull()))
      .Times(1)
      .WillOnce(testing::SaveArg<0>(&profile_created));
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .Times(1)
      .WillOnce(testing::SaveArg<0>(&profile_initialized));
  Profile* profile = profile_manager->GetProfile(profile_path);

  // The profile has been loaded correctly, and all callbacks were called.
  EXPECT_EQ(profile, profile_manager->GetProfileByPath(profile_path));
  testing::Mock::VerifyAndClearExpectations(&mock_observer);
  EXPECT_EQ(profile->GetPath(), profile_path);
  EXPECT_EQ(profile, profile_initialized);
  EXPECT_EQ(profile, profile_created);
}

#if !BUILDFLAG(IS_ANDROID)
// There's no multi-profiles on Android.
TEST_F(ProfileManagerTest, CreateMultiProfileAsync) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ASSERT_TRUE(profile_manager);

  const std::string profile_name = "New Profile";

  base::RunLoop run_loop;
  MockObserver mock_observer;
  Profile* profile = nullptr;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull()))
      .WillOnce(testing::SaveArg<0>(&profile));
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .WillOnce([&run_loop] { run_loop.Quit(); });

  CreateMultiProfileAsync(profile_manager, profile_name, &mock_observer);
  run_loop.Run();

  // Check that the profile name is set correctly both in the profile prefs and
  // in storage.
  ASSERT_NE(profile, nullptr);
  ProfileAttributesEntry* entry =
      profile_manager->GetProfileAttributesStorage()
          .GetProfileAttributesWithPath(profile->GetPath());
  ASSERT_NE(entry, nullptr);
  EXPECT_EQ(base::UTF16ToUTF8(entry->GetName()), profile_name);
  EXPECT_EQ(profile->GetPrefs()->GetString(prefs::kProfileName), profile_name);
}

TEST_F(ProfileManagerTest, CreateMultiProfilesAsync) {
  const std::string profile_name1 = "New Profile 1";
  const std::string profile_name2 = "New Profile 2";

  base::RunLoop run_loop;
  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull())).Times(2);
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .WillOnce(testing::Return())
      .WillOnce([&run_loop] { run_loop.Quit(); });

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  CreateMultiProfileAsync(profile_manager, profile_name1, &mock_observer);
  CreateMultiProfileAsync(profile_manager, profile_name2, &mock_observer);
  run_loop.Run();
}

TEST_F(ProfileManagerTest, CreateMultiProfileAsyncMultipleRequests) {
  base::RunLoop run_loop;
  MockObserver mock_observer;
  Profile *profile1 = nullptr, *profile2 = nullptr, *profile3 = nullptr;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull())).Times(3);
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .WillOnce(testing::SaveArg<0>(&profile1))
      .WillOnce(testing::SaveArg<0>(&profile2))
      .WillOnce(testing::DoAll(testing::SaveArg<0>(&profile3),
                               [&run_loop] { run_loop.Quit(); }));

  ProfileManager* profile_manager = g_browser_process->profile_manager();
  const std::string profile_name = "New Profile";
  CreateMultiProfileAsync(profile_manager, profile_name, &mock_observer);
  CreateMultiProfileAsync(profile_manager, profile_name, &mock_observer);
  CreateMultiProfileAsync(profile_manager, profile_name, &mock_observer);
  run_loop.Run();

  // A new profile should have been created for each call.
  EXPECT_NE(profile1, profile2);
  EXPECT_NE(profile1, profile3);
  EXPECT_NE(profile2, profile3);
}

TEST_F(ProfileManagerTest,
       CreateMultiProfilesAsyncWithBrokenPrefAndProfileInCache) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ASSERT_TRUE(profile_manager);

  // Simulate having "Profile 1" in the storage without properly incrementing
  // the prefs::kProfilesNumCreated counter.
  ProfileAttributesInitParams params_1;
  params_1.profile_path =
      profile_manager->user_data_dir().AppendASCII("Profile 1");
  params_1.profile_name = u"name_1";
  params_1.gaia_id = GaiaId("12345");
  params_1.is_consented_primary_account = true;
  profile_manager->GetProfileAttributesStorage().AddProfile(
      std::move(params_1));

  base::RunLoop run_loop;
  MockObserver mock_observer;
  Profile* profile2 = nullptr;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull()))
      .WillOnce(testing::SaveArg<0>(&profile2));
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .WillOnce([&run_loop] { run_loop.Quit(); });

  CreateMultiProfileAsync(profile_manager, "Profile B", &mock_observer);
  run_loop.Run();

  ASSERT_NE(profile2, nullptr);
  EXPECT_EQ(profile2->GetPath().BaseName().value(),
            FILE_PATH_LITERAL("Profile 2"));
  ProfileAttributesEntry* entry2 =
      profile_manager->GetProfileAttributesStorage()
          .GetProfileAttributesWithPath(profile2->GetPath());
  ASSERT_NE(entry2, nullptr);
}

TEST_F(ProfileManagerTest,
       PRE_CreateMultiProfilesAsyncWithBrokenPrefAndProfileOnDisk) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ASSERT_TRUE(profile_manager);

  base::RunLoop run_loop;
  MockObserver mock_observer;
  Profile* profile1 = nullptr;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull()))
      .WillOnce(testing::SaveArg<0>(&profile1));
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .WillOnce([&run_loop] { run_loop.Quit(); });
  CreateMultiProfileAsync(profile_manager, "Profile A", &mock_observer);
  run_loop.Run();

  ASSERT_NE(profile1, nullptr);
  EXPECT_EQ(profile1->GetPath().BaseName().value(),
            FILE_PATH_LITERAL("Profile 1"));
  ProfileAttributesEntry* entry1 =
      profile_manager->GetProfileAttributesStorage()
          .GetProfileAttributesWithPath(profile1->GetPath());
  ASSERT_NE(entry1, nullptr);

  // Decrement next profile number to simulate it was never incremented.
  EXPECT_EQ(TestingBrowserProcess::GetGlobal()->local_state()->GetInteger(
                prefs::kProfilesNumCreated),
            2);
  TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetUserPref(
      prefs::kProfilesNumCreated, std::make_unique<base::Value>(1));
  // Wipe the profile from profile attributes storage to simulate it got deleted
  // but not wiped from disk.
  profile_manager->GetProfileAttributesStorage().RemoveProfile(
      profile1->GetPath());
}

// We need to restart Chrome in the mean-time to make sure the profile is not
// loaded in memory.
TEST_F(ProfileManagerTest,
       CreateMultiProfilesAsyncWithBrokenPrefAndProfileOnDisk) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ASSERT_TRUE(profile_manager);

  base::RunLoop run_loop;
  MockObserver mock_observer;
  Profile* profile2 = nullptr;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull()))
      .WillOnce(testing::SaveArg<0>(&profile2));
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .WillOnce([&run_loop] { run_loop.Quit(); });
  CreateMultiProfileAsync(profile_manager, "Profile B", &mock_observer);
  run_loop.Run();

  ASSERT_NE(profile2, nullptr);
  // The profile uses the same base name as in the pre test.
  EXPECT_EQ(profile2->GetPath().BaseName().value(),
            FILE_PATH_LITERAL("Profile 1"));
  ProfileAttributesEntry* entry2 =
      profile_manager->GetProfileAttributesStorage()
          .GetProfileAttributesWithPath(profile2->GetPath());
  ASSERT_NE(entry2, nullptr);
  EXPECT_EQ(base::UTF16ToUTF8(entry2->GetName()), "Profile B");
}

TEST_F(ProfileManagerTest, CreateHiddenProfileAsync) {
  base::RunLoop run_loop;
  Profile* profile = nullptr;
  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull()))
      .WillOnce(testing::SaveArg<0>(&profile));
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .WillOnce([&run_loop] { run_loop.Quit(); });

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  profile_manager->CreateMultiProfileAsync(
      u"New Profile", 0, /*is_hidden=*/true,
      base::BindOnce(&MockObserver::OnProfileInitialized,
                     base::Unretained(&mock_observer)),
      base::BindOnce(&MockObserver::OnProfileCreated,
                     base::Unretained(&mock_observer)));

  run_loop.Run();
  ASSERT_NE(profile, nullptr);

  ProfileAttributesEntry* entry =
      profile_manager->GetProfileAttributesStorage()
          .GetProfileAttributesWithPath(profile->GetPath());
  ASSERT_NE(entry, nullptr);
  EXPECT_TRUE(entry->IsOmitted());
  EXPECT_TRUE(entry->IsEphemeral());
}
#endif  // !BUILDFLAG(IS_ANDROID)

// Checks that the supervised profiles no longer marked as omitted on creation.
TEST_F(ProfileManagerTest, AddProfileToStorageCheckNotOmitted) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  EXPECT_EQ(0u, storage.GetNumberOfProfiles());

  const base::FilePath supervised_path =
      temp_dir_.GetPath().AppendASCII("Supervised");
  auto supervised_profile = std::make_unique<TestingProfile>(
      supervised_path, nullptr, Profile::CreateMode::kSynchronous);
  supervised_profile->GetPrefs()->SetString(prefs::kSupervisedUserId,
                                            supervised_user::kChildAccountSUID);

  // RegisterTestingProfile adds the profile to the attributes storage and takes
  // ownership.
  profile_manager->RegisterTestingProfile(std::move(supervised_profile), true);
  ASSERT_EQ(1u, storage.GetNumberOfProfiles());
  EXPECT_FALSE(
      storage.GetAllProfilesAttributesSortedByNameWithCheck()[0]->IsOmitted());

  const base::FilePath nonsupervised_path =
      temp_dir_.GetPath().AppendASCII("Non-Supervised");
  auto nonsupervised_profile = std::make_unique<TestingProfile>(
      nonsupervised_path, nullptr, Profile::CreateMode::kSynchronous);
  profile_manager->RegisterTestingProfile(std::move(nonsupervised_profile),
                                          true);

  EXPECT_EQ(2u, storage.GetNumberOfProfiles());
  ProfileAttributesEntry* entry;
  entry = storage.GetProfileAttributesWithPath(supervised_path);
  ASSERT_NE(entry, nullptr);
  EXPECT_FALSE(entry->IsOmitted());

  entry = storage.GetProfileAttributesWithPath(nonsupervised_path);
  ASSERT_NE(entry, nullptr);
  EXPECT_FALSE(entry->IsOmitted());
}

#if !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
TEST_F(ProfileManagerTest, GetSystemProfilePath) {
  base::FilePath system_profile_path = ProfileManager::GetSystemProfilePath();
  base::FilePath expected_path = temp_dir_.GetPath();
  expected_path = expected_path.Append(chrome::kSystemProfileDir);
  EXPECT_EQ(expected_path, system_profile_path);
}
#endif  // !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)

// Test profile manager that creates all profiles as guest by default.
class UnittestGuestProfileManager : public FakeProfileManager {
 public:
  explicit UnittestGuestProfileManager(const base::FilePath& user_data_dir)
      : FakeProfileManager(user_data_dir) {}

  std::unique_ptr<TestingProfile> BuildTestingProfile(
      const base::FilePath& path,
      Delegate* delegate,
      Profile::CreateMode create_mode) override {
    TestingProfile::Builder builder;
    if (create_profiles_as_guest_)
      builder.SetGuestSession();
    builder.SetPath(path);
    builder.SetDelegate(delegate);
    builder.SetCreateMode(create_mode);
    return builder.Build();
  }

  void set_create_profiles_as_guest(bool create_profiles_as_guest) {
    create_profiles_as_guest_ = create_profiles_as_guest;
  }

 private:
  bool create_profiles_as_guest_ = true;
};

class ProfileManagerGuestTest : public ProfileManagerTest {
 public:
  ProfileManagerGuestTest() = default;
  ProfileManagerGuestTest(const ProfileManagerGuestTest&) = delete;
  ProfileManagerGuestTest& operator=(const ProfileManagerGuestTest&) = delete;
  ~ProfileManagerGuestTest() override = default;

  void SetUp() override {
#if BUILDFLAG(IS_CHROMEOS)
    base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
    cl->AppendSwitch(ash::switches::kGuestSession);
    cl->AppendSwitch(::switches::kIncognito);
#endif

    ProfileManagerTest::SetUp();

#if BUILDFLAG(IS_CHROMEOS)
    RegisterUser(user_manager::GuestAccountId());
#endif
  }

  // Call this function if the test shouldn't create all profiles as guest by
  // default.
  void DoNotCreateNewProfilesAsGuest() {
    unittest_profile_manager_->set_create_profiles_as_guest(false);
  }

 protected:
  std::unique_ptr<ProfileManager> CreateProfileManagerForTest() override {
    auto profile_manager_unique =
        std::make_unique<UnittestGuestProfileManager>(temp_dir_.GetPath());
    unittest_profile_manager_ = profile_manager_unique.get();
    return profile_manager_unique;
  }

 private:
  raw_ptr<UnittestGuestProfileManager, DanglingUntriaged>
      unittest_profile_manager_ = nullptr;
};

TEST_F(ProfileManagerGuestTest, GetLastUsedProfileAllowedByPolicy) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ASSERT_TRUE(profile_manager);

  Profile* profile = profile_manager->GetLastUsedProfileAllowedByPolicy();
  ASSERT_TRUE(profile);
  EXPECT_TRUE(profile->IsGuestSession());
  EXPECT_TRUE(profile->IsOffTheRecord());
}

#if BUILDFLAG(IS_CHROMEOS)
TEST_F(ProfileManagerGuestTest, GuestProfileIncognito) {
  Profile* primary_profile = ProfileManager::GetPrimaryUserProfile();
  EXPECT_TRUE(primary_profile->IsOffTheRecord());

  Profile* active_profile = ProfileManager::GetActiveUserProfile();
  EXPECT_TRUE(active_profile->IsOffTheRecord());

  EXPECT_TRUE(active_profile->IsSameOrParent(primary_profile));

  Profile* last_used_profile = ProfileManager::GetLastUsedProfile();
  EXPECT_TRUE(last_used_profile->IsOffTheRecord());

  EXPECT_TRUE(last_used_profile->IsSameOrParent(active_profile));
}
#endif

TEST_F(ProfileManagerGuestTest, GetGuestProfilePath) {
  base::FilePath guest_path = ProfileManager::GetGuestProfilePath();
  base::FilePath expected_path =
      temp_dir_.GetPath().AppendASCII("Guest Profile");
  EXPECT_EQ(expected_path, guest_path);
}

TEST_F(ProfileManagerGuestTest, GuestProfileAttributes) {
  // In these tests, the primary profile is a guest one.
  Profile* primary_profile = ProfileManager::GetLastUsedProfile();
  ASSERT_TRUE(primary_profile);
  ProfileAttributesEntry* entry =
      g_browser_process->profile_manager()
          ->GetProfileAttributesStorage()
          .GetProfileAttributesWithPath(primary_profile->GetPath());
  EXPECT_EQ(entry, nullptr);
}

TEST_F(ProfileManagerTest, AutoloadProfilesWithBackgroundApps) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetUserPref(
      prefs::kBackgroundModeEnabled, std::make_unique<base::Value>(true));

  // Setting a pref which is not applicable to a system (i.e., Android in this
  // case) does not necessarily create it. Don't bother continuing with the
  // test if this pref doesn't exist because it will not load the profiles if
  // it cannot verify that the pref for background mode is enabled.
  if (!TestingBrowserProcess::GetGlobal()->local_state()->HasPrefPath(
          prefs::kBackgroundModeEnabled)) {
    return;
  }

  EXPECT_EQ(0u, storage.GetNumberOfProfiles());

  ProfileAttributesInitParams params_1;
  params_1.profile_path =
      profile_manager->user_data_dir().AppendASCII("path_1");
  params_1.profile_name = u"name_1";
  params_1.gaia_id = GaiaId("12345");
  params_1.is_consented_primary_account = true;
  storage.AddProfile(std::move(params_1));
  ProfileAttributesInitParams params_2;
  params_2.profile_path =
      profile_manager->user_data_dir().AppendASCII("path_2");
  params_2.profile_name = u"name_2";
  params_2.gaia_id = GaiaId("23456");
  params_2.is_consented_primary_account = true;
  storage.AddProfile(std::move(params_2));
  ProfileAttributesInitParams params_3;
  params_3.profile_path =
      profile_manager->user_data_dir().AppendASCII("path_3");
  params_3.profile_name = u"name_3";
  params_3.gaia_id = GaiaId("34567");
  params_3.is_consented_primary_account = true;
  storage.AddProfile(std::move(params_3));

  ASSERT_EQ(3u, storage.GetNumberOfProfiles());

  std::vector<ProfileAttributesEntry*> entries =
      storage.GetAllProfilesAttributes();
  entries[0]->SetBackgroundStatus(true);
  entries[2]->SetBackgroundStatus(true);

  profile_manager->AutoloadProfiles();

  EXPECT_EQ(2u, profile_manager->GetLoadedProfiles().size());
}

TEST_F(ProfileManagerTest, DoNotAutoloadProfilesIfBackgroundModeOff) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  TestingBrowserProcess::GetGlobal()->GetTestingLocalState()->SetUserPref(
      prefs::kBackgroundModeEnabled, std::make_unique<base::Value>(false));

  EXPECT_EQ(0u, storage.GetNumberOfProfiles());

  ProfileAttributesInitParams params_1;
  params_1.profile_path =
      profile_manager->user_data_dir().AppendASCII("path_1");
  params_1.profile_name = u"name_1";
  params_1.gaia_id = GaiaId("12345");
  params_1.is_consented_primary_account = true;
  storage.AddProfile(std::move(params_1));
  ProfileAttributesInitParams params_2;
  params_2.profile_path =
      profile_manager->user_data_dir().AppendASCII("path_2");
  params_2.profile_name = u"name_2";
  params_2.gaia_id = GaiaId("23456");
  params_2.is_consented_primary_account = true;
  storage.AddProfile(std::move(params_2));

  ASSERT_EQ(2u, storage.GetNumberOfProfiles());

  std::vector<ProfileAttributesEntry*> entries =
      storage.GetAllProfilesAttributes();
  entries[0]->SetBackgroundStatus(false);
  entries[1]->SetBackgroundStatus(true);

  profile_manager->AutoloadProfiles();

  EXPECT_EQ(0u, profile_manager->GetLoadedProfiles().size());
}

TEST_F(ProfileManagerTest, InitProfileUserPrefs) {
  base::FilePath dest_path = temp_dir_.GetPath();
  dest_path = dest_path.Append(FILE_PATH_LITERAL("New Profile"));

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  Profile* profile;

  // Successfully create the profile
  profile = profile_manager->GetProfile(dest_path);
  ASSERT_TRUE(profile);

  // Check that the profile name is non empty
  std::string profile_name =
      profile->GetPrefs()->GetString(prefs::kProfileName);
  EXPECT_FALSE(profile_name.empty());

  // Check that the profile avatar index is valid
  size_t avatar_index =
      profile->GetPrefs()->GetInteger(prefs::kProfileAvatarIndex);
  EXPECT_TRUE(profiles::IsDefaultAvatarIconIndex(
      avatar_index));
}

// Tests that a new profile's entry in the profile attributes storage is setup
// with the same values that are in the profile prefs.
TEST_F(ProfileManagerTest, InitProfileAttributesStorageForAProfile) {
  base::FilePath dest_path = temp_dir_.GetPath();
  dest_path = dest_path.Append(FILE_PATH_LITERAL("New Profile"));

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  // Successfully create the profile
  Profile* profile = profile_manager->GetProfile(dest_path);
  ASSERT_TRUE(profile);

  std::string profile_name =
      profile->GetPrefs()->GetString(prefs::kProfileName);
  size_t avatar_index =
      profile->GetPrefs()->GetInteger(prefs::kProfileAvatarIndex);

  ProfileAttributesEntry* entry = profile_manager->GetProfileAttributesStorage()
                                      .GetProfileAttributesWithPath(dest_path);
  ASSERT_NE(entry, nullptr);

  // Check if the profile prefs are the same as the storage prefs.
  EXPECT_EQ(profile_name, base::UTF16ToUTF8(entry->GetName()));
  EXPECT_EQ(avatar_index, entry->GetAvatarIconIndex());
}

#if BUILDFLAG(IS_CHROMEOS)
TEST_F(ProfileManagerTest, InitProfileForChildOnFirstSignIn) {
  std::unique_ptr<Profile> profile = InitProfileForArcTransitionTest(
      true /* profile_is_new */, false /* arc_signed_in */,
      false /* profile_is_child */, true /* user_is_child */,
      false /* profile_is_managed */, false /* arc_is_managed */);

  EXPECT_EQ(
      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
      static_cast<int>(arc::ArcManagementTransition::NO_TRANSITION));
  EXPECT_EQ(profile->GetPrefs()->GetString(prefs::kSupervisedUserId),
            supervised_user::kChildAccountSUID);
}

TEST_F(ProfileManagerTest, InitProfileForRegularToChildTransition) {
  std::unique_ptr<Profile> profile = InitProfileForArcTransitionTest(
      false /* profile_is_new */, true /* arc_signed_in */,
      false /* profile_is_child */, true /* user_is_child */,
      false /* profile_is_managed */, false /* arc_is_managed */);

  EXPECT_EQ(
      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
      static_cast<int>(arc::ArcManagementTransition::REGULAR_TO_CHILD));
  EXPECT_EQ(profile->GetPrefs()->GetString(prefs::kSupervisedUserId),
            supervised_user::kChildAccountSUID);
}

TEST_F(ProfileManagerTest, InitProfileForChildToRegularTransition) {
  std::unique_ptr<Profile> profile = InitProfileForArcTransitionTest(
      false /* profile_is_new */, true /* arc_signed_in */,
      true /* profile_is_child */, false /* user_is_child */,
      true /* profile_is_managed */, false /* arc_is_managed */);

  EXPECT_EQ(
      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
      static_cast<int>(arc::ArcManagementTransition::CHILD_TO_REGULAR));
  EXPECT_TRUE(profile->GetPrefs()->GetString(prefs::kSupervisedUserId).empty());
}

TEST_F(ProfileManagerTest, InitProfileForUnmanagedToManagedTransition) {
  std::unique_ptr<Profile> profile = InitProfileForArcTransitionTest(
      false /* profile_is_new */, true /* arc_signed_in */,
      false /* profile_is_child */, false /* user_is_child */,
      true /* profile_is_managed */, false /* arc_is_managed */);

  EXPECT_EQ(
      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
      static_cast<int>(arc::ArcManagementTransition::UNMANAGED_TO_MANAGED));
}

TEST_F(ProfileManagerTest, InitProfileForManagedUserOnFirstSignIn) {
  std::unique_ptr<Profile> profile = InitProfileForArcTransitionTest(
      true /* profile_is_new */, false /* arc_signed_in */,
      false /* profile_is_child */, false /* user_is_child */,
      true /* profile_is_managed */, false /* arc_is_managed */);

  EXPECT_EQ(
      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
      static_cast<int>(arc::ArcManagementTransition::NO_TRANSITION));
}

TEST_F(ProfileManagerTest,
       InitProfileForChildToRegularTransitionArcNotSignedIn) {
  std::unique_ptr<Profile> profile = InitProfileForArcTransitionTest(
      false /* profile_is_new */, false /* arc_signed_in */,
      true /* profile_is_child */, false /* user_is_child */,
      true /* profile_is_managed */, false /* arc_is_managed */);

  EXPECT_EQ(
      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
      static_cast<int>(arc::ArcManagementTransition::NO_TRANSITION));
  EXPECT_TRUE(profile->GetPrefs()->GetString(prefs::kSupervisedUserId).empty());
}

TEST_F(ProfileManagerTest,
       InitProfileForManagedUserForFirstSignInOnNewVersion) {
  std::unique_ptr<Profile> profile = InitProfileForArcTransitionTest(
      false /* profile_is_new */, true /* arc_signed_in */,
      false /* profile_is_child */, false /* user_is_child */,
      true /* profile_is_managed */, std::nullopt /* arc_is_managed */);

  EXPECT_EQ(
      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
      static_cast<int>(arc::ArcManagementTransition::NO_TRANSITION));
}

TEST_F(ProfileManagerTest, InitProfileForChildUserForFirstSignInOnNewVersion) {
  std::unique_ptr<Profile> profile = InitProfileForArcTransitionTest(
      false /* profile_is_new */, true /* arc_signed_in */,
      true /* profile_is_child */, true /* user_is_child */,
      true /* profile_is_managed */, std::nullopt /* arc_is_managed */);

  EXPECT_EQ(
      profile->GetPrefs()->GetInteger(arc::prefs::kArcManagementTransition),
      static_cast<int>(arc::ArcManagementTransition::NO_TRANSITION));
  EXPECT_EQ(profile->GetPrefs()->GetString(prefs::kSupervisedUserId),
            supervised_user::kChildAccountSUID);
}

#endif

TEST_F(ProfileManagerTest, GetLastUsedProfileAllowedByPolicy) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ASSERT_TRUE(profile_manager);

#if BUILDFLAG(IS_CHROMEOS)
  // On CrOS, profile returned by GetLastUsedProfile is a sign-in profile that
  // is forced to be off-the-record. That's why we need to create at least one
  // user to get a regular profile.
  RegisterUser(AccountId::FromUserEmailGaiaId("test-user@example.com",
                                              GaiaId("1234567890")));
#endif

  Profile* profile = profile_manager->GetLastUsedProfileAllowedByPolicy();
  ASSERT_TRUE(profile);
  EXPECT_FALSE(profile->IsOffTheRecord());
  PrefService* prefs = profile->GetPrefs();
  EXPECT_EQ(IncognitoModePrefs::kDefaultAvailability,
            IncognitoModePrefs::GetAvailability(prefs));

  ASSERT_TRUE(profile->GetPrimaryOTRProfile(/*create_if_needed=*/true));

  IncognitoModePrefs::SetAvailability(
      prefs, policy::IncognitoModeAvailability::kDisabled);
  EXPECT_FALSE(
      profile_manager->GetLastUsedProfileAllowedByPolicy()->IsOffTheRecord());

  // GetLastUsedProfileAllowedByPolicy() returns the off-the-record Profile when
  // incognito mode is forced.
  IncognitoModePrefs::SetAvailability(
      prefs, policy::IncognitoModeAvailability::kForced);
  EXPECT_TRUE(
      profile_manager->GetLastUsedProfileAllowedByPolicy()->IsOffTheRecord());
}

#if !BUILDFLAG(IS_ANDROID)
// There's no Browser object on Android.
TEST_F(ProfileManagerTest, LastOpenedProfiles) {
  base::FilePath dest_path1 = temp_dir_.GetPath();
  dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1"));

  base::FilePath dest_path2 = temp_dir_.GetPath();
  dest_path2 = dest_path2.Append(FILE_PATH_LITERAL("New Profile 2"));

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  // Successfully create the profiles.
  TestingProfile* profile1 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path1));
  ASSERT_TRUE(profile1);

  TestingProfile* profile2 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path2));
  ASSERT_TRUE(profile2);

  std::vector<Profile*> last_opened_profiles =
      profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(0U, last_opened_profiles.size());
  EXPECT_FALSE(profile_manager->has_updated_last_opened_profiles());

  // Create a browser for profile1.
  Browser::CreateParams profile1_params(profile1, true);
  std::unique_ptr<Browser> browser1a(
      CreateBrowserWithTestWindowForParams(profile1_params));

  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(1U, last_opened_profiles.size());
  EXPECT_TRUE(profile_manager->has_updated_last_opened_profiles());
  EXPECT_EQ(profile1, last_opened_profiles[0]);

  // And for profile2.
  Browser::CreateParams profile2_params(profile2, true);
  std::unique_ptr<Browser> browser2(
      CreateBrowserWithTestWindowForParams(profile2_params));

  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(2U, last_opened_profiles.size());
  EXPECT_TRUE(profile_manager->has_updated_last_opened_profiles());
  EXPECT_EQ(profile1, last_opened_profiles[0]);
  EXPECT_EQ(profile2, last_opened_profiles[1]);

  // Adding more browsers doesn't change anything.
  std::unique_ptr<Browser> browser1b(
      CreateBrowserWithTestWindowForParams(profile1_params));
  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(2U, last_opened_profiles.size());
  EXPECT_TRUE(profile_manager->has_updated_last_opened_profiles());
  EXPECT_EQ(profile1, last_opened_profiles[0]);
  EXPECT_EQ(profile2, last_opened_profiles[1]);

  // Close the browsers.
  browser1a.reset();
  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(2U, last_opened_profiles.size());
  EXPECT_TRUE(profile_manager->has_updated_last_opened_profiles());
  EXPECT_EQ(profile1, last_opened_profiles[0]);
  EXPECT_EQ(profile2, last_opened_profiles[1]);

  browser1b.reset();
  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(1U, last_opened_profiles.size());
  EXPECT_TRUE(profile_manager->has_updated_last_opened_profiles());
  EXPECT_EQ(profile2, last_opened_profiles[0]);

  // `has_updated_last_opened_profiles()` should return true even after all
  // profiles have been cleared from the list.
  browser2.reset();
  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(0U, last_opened_profiles.size());
  EXPECT_TRUE(profile_manager->has_updated_last_opened_profiles());
}

TEST_F(ProfileManagerTest, LastOpenedProfilesAtShutdown) {
  base::FilePath dest_path1 = temp_dir_.GetPath();
  dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1"));

  base::FilePath dest_path2 = temp_dir_.GetPath();
  dest_path2 = dest_path2.Append(FILE_PATH_LITERAL("New Profile 2"));

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  // Successfully create the profiles.
  TestingProfile* profile1 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path1));
  ASSERT_TRUE(profile1);

  TestingProfile* profile2 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path2));
  ASSERT_TRUE(profile2);

  // Create a browser for profile1.
  Browser::CreateParams profile1_params(profile1, true);
  std::unique_ptr<Browser> browser1(
      CreateBrowserWithTestWindowForParams(profile1_params));

  // And for profile2.
  Browser::CreateParams profile2_params(profile2, true);
  std::unique_ptr<Browser> browser2(
      CreateBrowserWithTestWindowForParams(profile2_params));

  std::vector<Profile*> last_opened_profiles =
      profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(2U, last_opened_profiles.size());
  EXPECT_EQ(profile1, last_opened_profiles[0]);
  EXPECT_EQ(profile2, last_opened_profiles[1]);

  // Simulate a shutdown.
  chrome::OnClosingAllBrowsers(true);

  // Even if the browsers are destructed during shutdown, the profiles stay
  // open.
  browser1.reset();
  browser2.reset();

  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(2U, last_opened_profiles.size());
  EXPECT_EQ(profile1, last_opened_profiles[0]);
  EXPECT_EQ(profile2, last_opened_profiles[1]);
}

TEST_F(ProfileManagerTest, LastOpenedProfilesDoesNotContainIncognito) {
  base::FilePath dest_path1 = temp_dir_.GetPath();
  dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("New Profile 1"));
  base::FilePath dest_path2 = temp_dir_.GetPath();
  dest_path2 = dest_path2.Append(FILE_PATH_LITERAL("New Profile 2"));

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  // Successfully create the profiles.
  TestingProfile* profile1 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path1));
  ASSERT_TRUE(profile1);

  std::vector<Profile*> last_opened_profiles =
      profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(0U, last_opened_profiles.size());

  // Create a browser for profile1.
  Browser::CreateParams profile1_params(profile1, true);
  std::unique_ptr<Browser> browser1(
      CreateBrowserWithTestWindowForParams(profile1_params));

  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(1U, last_opened_profiles.size());
  EXPECT_EQ(profile1, last_opened_profiles[0]);

  // And for profile2.
  Browser::CreateParams profile2_params(
      profile1->GetPrimaryOTRProfile(/*create_if_needed=*/true), true);
  std::unique_ptr<Browser> browser2a(
      CreateBrowserWithTestWindowForParams(profile2_params));

  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(1U, last_opened_profiles.size());
  EXPECT_EQ(profile1, last_opened_profiles[0]);

  // Adding more browsers doesn't change anything.
  std::unique_ptr<Browser> browser2b(
      CreateBrowserWithTestWindowForParams(profile2_params));
  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(1U, last_opened_profiles.size());
  EXPECT_EQ(profile1, last_opened_profiles[0]);

  // Close the browsers.
  browser2a.reset();
  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(1U, last_opened_profiles.size());
  EXPECT_EQ(profile1, last_opened_profiles[0]);

  browser2b.reset();
  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(1U, last_opened_profiles.size());
  EXPECT_EQ(profile1, last_opened_profiles[0]);

  browser1.reset();
  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(0U, last_opened_profiles.size());
}
#endif  // !BUILDFLAG(IS_ANDROID)

#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
// There's no Browser object on Android and there's no multi-profiles on Chrome.
TEST_F(ProfileManagerTest, EphemeralProfilesDontEndUpAsLastProfile) {
  base::FilePath dest_path = temp_dir_.GetPath();
  dest_path = dest_path.Append(FILE_PATH_LITERAL("Ephemeral Profile"));

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  TestingProfile* profile =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path));
  ASSERT_TRUE(profile);
  SetProfileEphemeral(profile);

  // Here the last used profile is still the "Default" profile.
  Profile* last_used_profile = profile_manager->GetLastUsedProfile();
  EXPECT_NE(profile, last_used_profile);

  // Create a browser for the profile.
  Browser::CreateParams profile_params(profile, true);
  std::unique_ptr<Browser> browser(
      CreateBrowserWithTestWindowForParams(profile_params));
  last_used_profile = profile_manager->GetLastUsedProfile();
  EXPECT_NE(profile, last_used_profile);

  // Close the browser.
  browser.reset();
  last_used_profile = profile_manager->GetLastUsedProfile();
  EXPECT_NE(profile, last_used_profile);
}

TEST_F(ProfileManagerTest, EphemeralProfilesDontEndUpAsLastOpenedAtShutdown) {
  base::FilePath dest_path1 = temp_dir_.GetPath();
  dest_path1 = dest_path1.Append(FILE_PATH_LITERAL("Normal Profile"));

  base::FilePath dest_path2 = temp_dir_.GetPath();
  dest_path2 = dest_path2.Append(FILE_PATH_LITERAL("Ephemeral Profile 1"));

  base::FilePath dest_path3 = temp_dir_.GetPath();
  dest_path3 = dest_path3.Append(FILE_PATH_LITERAL("Ephemeral Profile 2"));

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  // Successfully create the profiles.
  TestingProfile* normal_profile =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path1));
  ASSERT_TRUE(normal_profile);

  // Add one ephemeral profile which should not end up in this list.
  TestingProfile* ephemeral_profile1 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path2));
  ASSERT_TRUE(ephemeral_profile1);
  SetProfileEphemeral(ephemeral_profile1);

  // Add second ephemeral profile but don't mark it as such yet.
  TestingProfile* ephemeral_profile2 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path3));
  ASSERT_TRUE(ephemeral_profile2);

  // Create a browser for profile1.
  Browser::CreateParams profile1_params(normal_profile, true);
  std::unique_ptr<Browser> browser1(
      CreateBrowserWithTestWindowForParams(profile1_params));

  // Create browsers for the ephemeral profile.
  Browser::CreateParams profile2_params(ephemeral_profile1, true);
  std::unique_ptr<Browser> browser2(
      CreateBrowserWithTestWindowForParams(profile2_params));

  Browser::CreateParams profile3_params(ephemeral_profile2, true);
  std::unique_ptr<Browser> browser3(
      CreateBrowserWithTestWindowForParams(profile3_params));

  std::vector<Profile*> last_opened_profiles =
      profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(2U, last_opened_profiles.size());
  EXPECT_EQ(normal_profile, last_opened_profiles[0]);
  EXPECT_EQ(ephemeral_profile2, last_opened_profiles[1]);

  // Mark the second profile ephemeral.
  SetProfileEphemeral(ephemeral_profile2);

  // Simulate a shutdown.
  chrome::OnClosingAllBrowsers(true);
  browser1.reset();
  browser2.reset();
  browser3.reset();

  last_opened_profiles = profile_manager->GetLastOpenedProfiles();
  ASSERT_EQ(1U, last_opened_profiles.size());
  EXPECT_EQ(normal_profile, last_opened_profiles[0]);
}

TEST_F(ProfileManagerTest, CleanUpEphemeralProfiles) {
  // Create two profiles, one of them ephemeral.
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  ASSERT_EQ(0u, storage.GetNumberOfProfiles());

  const std::string profile_name1 = "Homer";
  base::FilePath path1 =
      profile_manager->user_data_dir().AppendASCII(profile_name1);
  ProfileAttributesInitParams params_1;
  params_1.profile_path = path1;
  params_1.profile_name = base::UTF8ToUTF16(profile_name1);
  params_1.user_name = base::UTF8ToUTF16(profile_name1);
  params_1.is_consented_primary_account = true;
  storage.AddProfile(std::move(params_1));
  storage.GetAllProfilesAttributes()[0]->SetIsEphemeral(true);
  ASSERT_TRUE(base::CreateDirectory(path1));

  const std::string profile_name2 = "Marge";
  base::FilePath path2 =
      profile_manager->user_data_dir().AppendASCII(profile_name2);
  ProfileAttributesInitParams params_2;
  params_2.profile_path = path2;
  params_2.profile_name = base::UTF8ToUTF16(profile_name2);
  params_2.user_name = base::UTF8ToUTF16(profile_name2);
  params_2.is_consented_primary_account = true;
  storage.AddProfile(std::move(params_2));
  ASSERT_EQ(2u, storage.GetNumberOfProfiles());
  ASSERT_TRUE(base::CreateDirectory(path2));

  // Set the active profile.
  PrefService* local_state = TestingBrowserProcess::GetGlobal()->local_state();
  local_state->SetString(prefs::kProfileLastUsed, profile_name1);

  // Set the last used profiles.
  ScopedListPrefUpdate update(local_state, prefs::kProfilesLastActive);
  base::Value::List& initial_last_active_profile_list = update.Get();
  initial_last_active_profile_list.Append(
      base::Value(path1.BaseName().MaybeAsASCII()));
  initial_last_active_profile_list.Append(
      base::Value(path2.BaseName().MaybeAsASCII()));

  profile_manager->GetDeleteProfileHelper().CleanUpEphemeralProfiles();
  content::RunAllTasksUntilIdle();
  const base::Value::List& final_last_active_profile_list =
      local_state->GetList(prefs::kProfilesLastActive);

  // The ephemeral profile should be deleted, and the last used profile set to
  // the other one. Also, the ephemeral profile should be removed from the
  // kProfilesLastActive list.
  EXPECT_FALSE(base::DirectoryExists(path1));
  EXPECT_TRUE(base::DirectoryExists(path2));
  EXPECT_EQ(profile_name2, local_state->GetString(prefs::kProfileLastUsed));
  ASSERT_EQ(1u, storage.GetNumberOfProfiles());
  ASSERT_EQ(1u, final_last_active_profile_list.size());
  ASSERT_EQ(path2.BaseName().MaybeAsASCII(),
            (final_last_active_profile_list)[0].GetString());

  // Mark the remaining profile ephemeral and clean up.
  storage.GetAllProfilesAttributes()[0]->SetIsEphemeral(true);
  profile_manager->GetDeleteProfileHelper().CleanUpEphemeralProfiles();
  content::RunAllTasksUntilIdle();

  // The profile should be deleted, and the last used profile set to a new one.
  EXPECT_FALSE(base::DirectoryExists(path2));
  EXPECT_EQ(0u, storage.GetNumberOfProfiles());
  EXPECT_EQ("Profile 1", local_state->GetString(prefs::kProfileLastUsed));
  ASSERT_EQ(0u, final_last_active_profile_list.size());
}

TEST_F(ProfileManagerGuestTest, CleanUpOnlyEphemeralProfiles) {
  // Create two profiles, one of them is guest.
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  ASSERT_EQ(0u, storage.GetNumberOfProfiles());

  // Create the guest profile and register it.
  base::FilePath guest_path = ProfileManager::GetGuestProfilePath();
  const std::string guest_profile_name = guest_path.BaseName().MaybeAsASCII();
  TestingProfile::Builder builder;
  builder.SetGuestSession();
  builder.SetPath(guest_path);
  builder.SetProfileName(guest_profile_name);
  std::unique_ptr<TestingProfile> guest_profile = builder.Build();
  profile_manager->RegisterTestingProfile(std::move(guest_profile), true);

  // Create a regular profile.
  const std::string profile_name = "Homer";
  base::FilePath path =
      profile_manager->user_data_dir().AppendASCII(profile_name);
  ProfileAttributesInitParams params;
  params.profile_path = path;
  params.profile_name = base::UTF8ToUTF16(profile_name);
  params.user_name = base::UTF8ToUTF16(profile_name);
  params.is_consented_primary_account = true;
  storage.AddProfile(std::move(params));
  ASSERT_TRUE(base::CreateDirectory(path));

  ASSERT_EQ(1u, storage.GetNumberOfProfiles());

  // Set the active profile.
  PrefService* local_state = TestingBrowserProcess::GetGlobal()->local_state();
  local_state->SetString(prefs::kProfileLastUsed, guest_profile_name);

  // Set the last used profiles.
  ScopedListPrefUpdate update(local_state, prefs::kProfilesLastActive);
  base::Value::List& initial_last_active_profile_list = update.Get();
  initial_last_active_profile_list.Append(
      base::Value(guest_path.BaseName().MaybeAsASCII()));
  initial_last_active_profile_list.Append(
      base::Value(path.BaseName().MaybeAsASCII()));

  profile_manager->GetDeleteProfileHelper().CleanUpEphemeralProfiles();
  content::RunAllTasksUntilIdle();
  const base::Value::List& final_last_active_profile_list =
      local_state->GetList(prefs::kProfilesLastActive);

  // The guest and the non-ephemeral regular profile aren't impacted.
  EXPECT_TRUE(base::DirectoryExists(guest_path));
  EXPECT_TRUE(base::DirectoryExists(path));
  EXPECT_EQ(guest_profile_name,
            local_state->GetString(prefs::kProfileLastUsed));
  ASSERT_EQ(1u, storage.GetNumberOfProfiles());
  ASSERT_EQ(2u, final_last_active_profile_list.size());
  ASSERT_EQ(guest_path.BaseName().MaybeAsASCII(),
            (final_last_active_profile_list)[0].GetString());
}

TEST_F(ProfileManagerTest, CleanUpEphemeralProfilesWithGuestLastUsedProfile) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  ASSERT_EQ(0u, storage.GetNumberOfProfiles());

  const std::string profile_name1 = "Homer";
  base::FilePath path1 =
      profile_manager->user_data_dir().AppendASCII(profile_name1);
  ProfileAttributesInitParams params;
  params.profile_path = path1;
  params.profile_name = base::UTF8ToUTF16(profile_name1);
  params.user_name = base::UTF8ToUTF16(profile_name1);
  params.is_consented_primary_account = true;
  storage.AddProfile(std::move(params));
  storage.GetAllProfilesAttributes()[0]->SetIsEphemeral(true);
  ASSERT_TRUE(base::CreateDirectory(path1));
  ASSERT_EQ(1u, storage.GetNumberOfProfiles());

  // Set the active profile.
  PrefService* local_state = TestingBrowserProcess::GetGlobal()->local_state();
  local_state->SetString(prefs::kProfileLastUsed, std::string("Guest Profile"));

  profile_manager->GetDeleteProfileHelper().CleanUpEphemeralProfiles();
  content::RunAllTasksUntilIdle();

  ASSERT_EQ(0u, storage.GetNumberOfProfiles());
  EXPECT_EQ("Profile 1", local_state->GetString(prefs::kProfileLastUsed));
}

TEST_F(ProfileManagerTest, DestroyProfileOnBrowserClose) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(features::kDestroyProfileOnBrowserClose);

  base::FilePath dest_path1 = temp_dir_.GetPath().AppendASCII("New Profile 1");
  base::FilePath dest_path2 = temp_dir_.GetPath().AppendASCII("New Profile 2");

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  TestingProfile* profile1 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path1));
  ASSERT_TRUE(profile1);
  TestingProfile* profile2 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path2));
  ASSERT_TRUE(profile2);

  // Create a browser for profile2.
  Browser::CreateParams profile_params2(profile2, true);
  std::unique_ptr<Browser> browser2(
      CreateBrowserWithTestWindowForParams(profile_params2));

  EXPECT_TRUE(profile_manager->IsValidProfile(profile1));
  EXPECT_TRUE(profile_manager->IsValidProfile(profile2));

  // Close the browser for profile2.
  browser2.reset();
  content::RunAllTasksUntilIdle();

  EXPECT_TRUE(profile_manager->IsValidProfile(profile1));
  EXPECT_FALSE(profile_manager->IsValidProfile(profile2));
}

TEST_F(ProfileManagerTest, DestroyEphemeralProfileOnBrowserClose) {
  base::test::ScopedFeatureList feature_list;
  feature_list.InitAndEnableFeature(features::kDestroyProfileOnBrowserClose);

  base::FilePath dest_path1 = temp_dir_.GetPath().AppendASCII("New Profile 1");
  base::FilePath dest_path2 = temp_dir_.GetPath().AppendASCII("New Profile 2");

  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();

  // Create 2 ephemeral profiles.
  TestingProfile* profile1 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path1));
  ASSERT_TRUE(profile1);
  SetProfileEphemeral(profile1);
  TestingProfile* profile2 =
      static_cast<TestingProfile*>(profile_manager->GetProfile(dest_path2));
  ASSERT_TRUE(profile2);
  SetProfileEphemeral(profile2);

  content::RunAllTasksUntilIdle();
  Profile* last_used_profile = profile_manager->GetLastUsedProfile();
  EXPECT_NE(profile1, last_used_profile);
  EXPECT_NE(profile2, last_used_profile);
  EXPECT_EQ(3u, storage.GetNumberOfProfiles());
  EXPECT_TRUE(base::PathExists(dest_path1));
  EXPECT_TRUE(base::PathExists(dest_path2));

  // Create a browser for profile2.
  Browser::CreateParams profile_params2(profile2, true);
  std::unique_ptr<Browser> browser2(
      CreateBrowserWithTestWindowForParams(profile_params2));

  // All asynchronous profile loading must complete to prevent accidental
  // reconstruction of profile2's path. This happens because
  // SimpleBackendImpl::InitializeIndex() is performed async which, if not
  // allowed to complete, may be performed after browser2.reset() and profile
  // path deletion.
  content::RunAllTasksUntilIdle();

  ProfileDeletionWaiter waiter(profile2);

  // Confirm that we are not currently waiting for the profile to be destroyed.
  ASSERT_FALSE(IsProfileDirectoryMarkedForDeletion(dest_path2));

  // Destroy the browser and let browser close tasks run.
  browser2.reset();
  content::RunAllTasksUntilIdle();

  // Confirm that either we have marked profile2's path for deletion or the path
  // has been deleted.
  ASSERT_TRUE(IsProfileDirectoryMarkedForDeletion(dest_path2) ||
              !base::PathExists(dest_path2));

  waiter.Wait();
  EXPECT_FALSE(base::PathExists(dest_path2));

  last_used_profile = profile_manager->GetLastUsedProfile();
  EXPECT_NE(profile1, last_used_profile);
  EXPECT_NE(profile2, last_used_profile);
  EXPECT_EQ(2u, storage.GetNumberOfProfiles());
  EXPECT_TRUE(base::PathExists(dest_path1));
}

TEST_F(ProfileManagerTest, ActiveProfileDeleted) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ASSERT_TRUE(profile_manager);

  // Create and load two profiles.
  const std::string profile_basename1 = "New Profile 1";
  const std::string profile_basename2 = "New Profile 2";
  base::FilePath profile_path1 =
      temp_dir_.GetPath().AppendASCII(profile_basename1);
  base::FilePath profile_path2 =
      temp_dir_.GetPath().AppendASCII(profile_basename2);

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .Times(testing::AtLeast(2));
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull()))
      .Times(testing::AtLeast(2));

  CreateProfileAsync(profile_manager, profile_path1, &mock_observer);
  CreateProfileAsync(profile_manager, profile_path2, &mock_observer);
  content::RunAllTasksUntilIdle();

  EXPECT_EQ(2u, profile_manager->GetLoadedProfiles().size());
  EXPECT_EQ(
      2u, profile_manager->GetProfileAttributesStorage().GetNumberOfProfiles());

  // Set the active profile.
  PrefService* local_state = TestingBrowserProcess::GetGlobal()->local_state();
  local_state->SetString(prefs::kProfileLastUsed, profile_basename1);

  // Delete the active profile.
  profile_manager->GetDeleteProfileHelper().MaybeScheduleProfileForDeletion(
      profile_path1, base::DoNothing(),
      ProfileMetrics::DELETE_PROFILE_USER_MANAGER);
  content::RunAllTasksUntilIdle();

  EXPECT_EQ(profile_path2, profile_manager->GetLastUsedProfile()->GetPath());
  EXPECT_EQ(profile_basename2, local_state->GetString(prefs::kProfileLastUsed));
}

TEST_F(ProfileManagerTest, LastProfileDeleted) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ASSERT_TRUE(profile_manager);
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();

  // Create and load a profile.
  const std::string profile_basename1 = "New Profile 1";
  base::FilePath profile_path1 =
      temp_dir_.GetPath().AppendASCII(profile_basename1);

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .Times(testing::AtLeast(1));

  CreateProfileAsync(profile_manager, profile_path1, &mock_observer);
  content::RunAllTasksUntilIdle();

  EXPECT_EQ(1u, profile_manager->GetLoadedProfiles().size());
  EXPECT_EQ(1u, storage.GetNumberOfProfiles());

  // Set it as the active profile.
  PrefService* local_state = TestingBrowserProcess::GetGlobal()->local_state();
  local_state->SetString(prefs::kProfileLastUsed, profile_basename1);

  // Delete the active profile.
  profile_manager->GetDeleteProfileHelper().MaybeScheduleProfileForDeletion(
      profile_path1, base::DoNothing(),
      ProfileMetrics::DELETE_PROFILE_USER_MANAGER);
  content::RunAllTasksUntilIdle();

  // A new profile should have been created
  const std::string profile_basename2 = "Profile 1";
  base::FilePath profile_path2 =
      temp_dir_.GetPath().AppendASCII(profile_basename2);

  EXPECT_EQ(profile_path2, profile_manager->GetLastUsedProfile()->GetPath());
  EXPECT_EQ(profile_basename2, local_state->GetString(prefs::kProfileLastUsed));
  ASSERT_EQ(1u, storage.GetNumberOfProfiles());
  EXPECT_EQ(profile_path2, storage.GetAllProfilesAttributes()[0]->GetPath());
}

TEST_F(ProfileManagerGuestTest, LastProfileDeletedWithGuestActiveProfile) {
  // Make new profiles to be created as non-guest by default.
  DoNotCreateNewProfilesAsGuest();

  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ASSERT_TRUE(profile_manager);
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();

  // Create and load a profile.
  const std::string profile_basename1 = "New Profile 1";
  base::FilePath profile_path1 =
      temp_dir_.GetPath().AppendASCII(profile_basename1);

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull()))
      .Times(testing::AtLeast(1));
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .Times(testing::AtLeast(1));

  CreateProfileAsync(profile_manager, profile_path1, &mock_observer);
  content::RunAllTasksUntilIdle();

  EXPECT_EQ(1u, profile_manager->GetLoadedProfiles().size());
  EXPECT_EQ(1u, storage.GetNumberOfProfiles());

  // Create the profile and register it.
  const std::string guest_profile_basename =
      ProfileManager::GetGuestProfilePath().BaseName().MaybeAsASCII();

  TestingProfile::Builder builder;
  builder.SetGuestSession();
  builder.SetPath(ProfileManager::GetGuestProfilePath());
  std::unique_ptr<TestingProfile> guest_profile = builder.Build();
  guest_profile->set_profile_name(guest_profile_basename);
  profile_manager->RegisterTestingProfile(std::move(guest_profile), false);

  // The Guest profile does not get added to the ProfileAttributesStorage.
  EXPECT_EQ(2u, profile_manager->GetLoadedProfiles().size());
  EXPECT_EQ(1u, storage.GetNumberOfProfiles());

  // Set the Guest profile as the active profile.
  PrefService* local_state = TestingBrowserProcess::GetGlobal()->local_state();
  local_state->SetString(prefs::kProfileLastUsed, guest_profile_basename);

  // Delete the other profile.
  profile_manager->GetDeleteProfileHelper().MaybeScheduleProfileForDeletion(
      profile_path1, base::DoNothing(),
      ProfileMetrics::DELETE_PROFILE_USER_MANAGER);
  content::RunAllTasksUntilIdle();

  // A new profile should have been created.
  const std::string profile_basename2 = "Profile 1";
  base::FilePath profile_path2 =
      temp_dir_.GetPath().AppendASCII(profile_basename2);

  if (base::FeatureList::IsEnabled(features::kDestroyProfileOnBrowserClose))
    EXPECT_EQ(2u, profile_manager->GetLoadedProfiles().size());
  else
    EXPECT_EQ(3u, profile_manager->GetLoadedProfiles().size());
  ASSERT_EQ(1u, storage.GetNumberOfProfiles());
  EXPECT_EQ(profile_path2, storage.GetAllProfilesAttributes()[0]->GetPath());
}

TEST_F(ProfileManagerTest, ProfileDisplayNameResetsDefaultName) {
  if (!profiles::IsMultipleProfilesEnabled())
    return;

  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  EXPECT_EQ(0u, storage.GetNumberOfProfiles());

  // Only one local profile means we display IDS_SINGLE_PROFILE_DISPLAY_NAME.
  const std::u16string default_profile_name =
      l10n_util::GetStringUTF16(IDS_SINGLE_PROFILE_DISPLAY_NAME);
  const std::u16string profile_name1 = storage.ChooseNameForNewProfile();
  Profile* profile1 = AddProfileToStorage(profile_manager,
                                          "path_1", profile_name1);
  EXPECT_EQ(default_profile_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));

  // Multiple profiles means displaying the actual profile names.
  const std::u16string profile_name2 = storage.ChooseNameForNewProfile();
  Profile* profile2 = AddProfileToStorage(profile_manager,
                                          "path_2", profile_name2);
  EXPECT_EQ(profile_name1,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));
  EXPECT_EQ(profile_name2,
            profiles::GetAvatarNameForProfile(profile2->GetPath()));

  // Deleting a profile means returning to the default name.
  profile_manager->GetDeleteProfileHelper().MaybeScheduleProfileForDeletion(
      profile2->GetPath(), base::DoNothing(),
      ProfileMetrics::DELETE_PROFILE_USER_MANAGER);
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(default_profile_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));
}

TEST_F(ProfileManagerTest, ProfileDisplayNamePreservesCustomName) {
  if (!profiles::IsMultipleProfilesEnabled())
    return;

  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  EXPECT_EQ(0u, storage.GetNumberOfProfiles());

  // Only one local profile means we display IDS_SINGLE_PROFILE_DISPLAY_NAME.
  const std::u16string default_profile_name =
      l10n_util::GetStringUTF16(IDS_SINGLE_PROFILE_DISPLAY_NAME);
  const std::u16string profile_name1 = storage.ChooseNameForNewProfile();
  Profile* profile1 = AddProfileToStorage(profile_manager,
                                          "path_1", profile_name1);
  EXPECT_EQ(default_profile_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));
  ASSERT_EQ(1u, storage.GetNumberOfProfiles());

  // We should display custom names for local profiles.
  const std::u16string custom_profile_name = u"Batman";
  ProfileAttributesEntry* entry = storage.GetAllProfilesAttributes()[0];
  entry->SetLocalProfileName(custom_profile_name, false);
  EXPECT_EQ(custom_profile_name, entry->GetName());
  EXPECT_EQ(custom_profile_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));

  // Multiple profiles means displaying the actual profile names.
  const std::u16string profile_name2 = storage.ChooseNameForNewProfile();
  Profile* profile2 = AddProfileToStorage(profile_manager,
                                          "path_2", profile_name2);
  EXPECT_EQ(custom_profile_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));
  EXPECT_EQ(profile_name2,
            profiles::GetAvatarNameForProfile(profile2->GetPath()));

  // Deleting a profile means returning to the original, custom name.
  profile_manager->GetDeleteProfileHelper().MaybeScheduleProfileForDeletion(
      profile2->GetPath(), base::DoNothing(),
      ProfileMetrics::DELETE_PROFILE_USER_MANAGER);
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(custom_profile_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));
}

TEST_F(ProfileManagerTest, ProfileDisplayNamePreservesSignedInName) {
  if (!profiles::IsMultipleProfilesEnabled())
    return;

  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  EXPECT_EQ(0u, storage.GetNumberOfProfiles());

  // Only one local profile means we display IDS_SINGLE_PROFILE_DISPLAY_NAME.
  const std::u16string default_profile_name =
      l10n_util::GetStringUTF16(IDS_SINGLE_PROFILE_DISPLAY_NAME);
  const std::u16string profile_name1 = storage.ChooseNameForNewProfile();
  Profile* profile1 = AddProfileToStorage(profile_manager,
                                          "path_1", profile_name1);
  EXPECT_EQ(default_profile_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));

  ASSERT_EQ(1u, storage.GetNumberOfProfiles());
  ProfileAttributesEntry* entry = storage.GetAllProfilesAttributes()[0];
  // For a signed in profile with a default name we still display
  // IDS_SINGLE_PROFILE_DISPLAY_NAME.
  entry->SetAuthInfo(GaiaId("12345"), u"user@gmail.com", true);
  EXPECT_EQ(profile_name1, entry->GetName());
  EXPECT_EQ(default_profile_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));

  // For a signed in profile with a non-default Gaia given name we display the
  // Gaia given name.
  entry->SetAuthInfo(GaiaId("12345"), u"user@gmail.com", true);
  const std::u16string gaia_given_name(u"given name");
  entry->SetGAIAGivenName(gaia_given_name);
  EXPECT_EQ(gaia_given_name, entry->GetName());
  EXPECT_EQ(gaia_given_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));

  // Multiple profiles means displaying the actual profile names.
  const std::u16string profile_name2 = storage.ChooseNameForNewProfile();
  Profile* profile2 = AddProfileToStorage(profile_manager,
                                          "path_2", profile_name2);
  EXPECT_EQ(gaia_given_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));
  EXPECT_EQ(profile_name2,
            profiles::GetAvatarNameForProfile(profile2->GetPath()));

  // Deleting a profile means returning to the original, actual profile name.
  profile_manager->GetDeleteProfileHelper().MaybeScheduleProfileForDeletion(
      profile2->GetPath(), base::DoNothing(),
      ProfileMetrics::DELETE_PROFILE_USER_MANAGER);
  content::RunAllTasksUntilIdle();
  EXPECT_EQ(gaia_given_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));
}
#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)

// GetAvatarNameForProfile() is not defined on Android.
#if !BUILDFLAG(IS_ANDROID)
TEST_F(ProfileManagerTest, ProfileDisplayNameIsEmailIfDefaultName) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  EXPECT_EQ(0u, storage.GetNumberOfProfiles());

  // Create two signed in profiles, with both new and legacy default names, and
  // a profile with a custom name.
  Profile* profile1 =
      AddProfileToStorage(profile_manager, "path_1", u"Person 1");
  Profile* profile2 =
      AddProfileToStorage(profile_manager, "path_2", u"Default Profile");
  const std::u16string profile_name3(u"Batman");
  Profile* profile3 = AddProfileToStorage(profile_manager, "path_3",
                                          profile_name3);
  EXPECT_EQ(3u, storage.GetNumberOfProfiles());

  // Sign in all profiles, and make sure they do not have a Gaia name set.
  const std::u16string email1(u"user1@gmail.com");
  const std::u16string email2(u"user2@gmail.com");
  const std::u16string email3(u"user3@gmail.com");

  ProfileAttributesEntry* entry =
      storage.GetProfileAttributesWithPath(profile1->GetPath());

  ASSERT_NE(entry, nullptr);
  entry->SetAuthInfo(GaiaId("12345"), email1, true);
  entry->SetGAIAGivenName(std::u16string());
  entry->SetGAIAName(std::u16string());

  entry = storage.GetProfileAttributesWithPath(profile2->GetPath());
  ASSERT_NE(entry, nullptr);
#if !BUILDFLAG(IS_CHROMEOS)
  // (Default profile, Batman,..) are legacy profile names on Desktop and are
  // not considered default profile names for newly created profiles.
  // We use "Person %n" as the default profile name. Set |SetIsUsingDefaultName|
  // manually to mimick pre-existing profiles.
  entry->SetLocalProfileName(u"Default Profile", true);
#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)

  entry->SetAuthInfo(GaiaId("23456"), email2, true);
  entry->SetGAIAGivenName(std::u16string());
  entry->SetGAIAName(std::u16string());

  entry = storage.GetProfileAttributesWithPath(profile3->GetPath());
  ASSERT_NE(entry, nullptr);

  entry->SetAuthInfo(GaiaId("34567"), email3, true);
  entry->SetGAIAGivenName(std::u16string());
  entry->SetGAIAName(std::u16string());

  // The profiles with default names should display the email address.
  EXPECT_EQ(email1, profiles::GetAvatarNameForProfile(profile1->GetPath()));
  EXPECT_EQ(email2, profiles::GetAvatarNameForProfile(profile2->GetPath()));

  // The profile with the custom name should display that.
  EXPECT_EQ(profile_name3,
            profiles::GetAvatarNameForProfile(profile3->GetPath()));

  // Adding a Gaia name to a profile that previously had a default name should
  // start displaying it.
  const std::u16string gaia_given_name(u"Robin");
  entry = storage.GetProfileAttributesWithPath(profile1->GetPath());
  ASSERT_NE(entry, nullptr);
  entry->SetGAIAGivenName(gaia_given_name);
  EXPECT_EQ(gaia_given_name,
            profiles::GetAvatarNameForProfile(profile1->GetPath()));
}
#endif  // !BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(IS_MAC)
// These tests are for a Mac-only code path that assumes the browser
// process isn't killed when all browser windows are closed.
TEST_F(ProfileManagerTest, ActiveProfileDeletedNeedsToLoadNextProfile) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ASSERT_TRUE(profile_manager);

  // Create and load one profile, and just create a second profile.
  const std::string profile_basename1 = "New Profile 1";
  const std::string profile_basename2 = "New Profile 2";
  base::FilePath profile_path1 =
      temp_dir_.GetPath().AppendASCII(profile_basename1);
  base::FilePath profile_path2 =
      temp_dir_.GetPath().AppendASCII(profile_basename2);

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull()))
      .Times(testing::AtLeast(1));
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .Times(testing::AtLeast(1));
  CreateProfileAsync(profile_manager, profile_path1, &mock_observer);
  content::RunAllTasksUntilIdle();

  // Track the profile, but don't load it.
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  ProfileAttributesInitParams params;
  params.profile_path = profile_path2;
  params.profile_name = ASCIIToUTF16(profile_basename2);
  params.gaia_id = GaiaId("23456");
  params.is_consented_primary_account = true;
  storage.AddProfile(std::move(params));
  content::RunAllTasksUntilIdle();

  EXPECT_EQ(1u, profile_manager->GetLoadedProfiles().size());
  EXPECT_EQ(2u, storage.GetNumberOfProfiles());

  // Set the active profile.
  PrefService* local_state = TestingBrowserProcess::GetGlobal()->local_state();
  local_state->SetString(prefs::kProfileLastUsed, profile_basename1);

  // Delete the active profile. This should switch and load the unloaded
  // profile.
  profile_manager->GetDeleteProfileHelper().MaybeScheduleProfileForDeletion(
      profile_path1, base::DoNothing(),
      ProfileMetrics::DELETE_PROFILE_USER_MANAGER);

  content::RunAllTasksUntilIdle();

  EXPECT_EQ(profile_path2, profile_manager->GetLastUsedProfile()->GetPath());
  EXPECT_EQ(profile_basename2, local_state->GetString(prefs::kProfileLastUsed));
}

// This tests the recursive call in ProfileManager::OnNewActiveProfileLoaded
// by simulating a scenario in which the profile that is being loaded as
// the next active profile has also been marked for deletion, so the
// ProfileManager needs to recursively select a different next profile.
TEST_F(ProfileManagerTest, ActiveProfileDeletedNextProfileDeletedToo) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  ASSERT_TRUE(profile_manager);

  // Create and load one profile, and create two more profiles.
  const std::string profile_basename1 = "New Profile 1";
  const std::string profile_basename2 = "New Profile 2";
  const std::string profile_basename3 = "New Profile 3";
  base::FilePath profile_path1 =
      temp_dir_.GetPath().AppendASCII(profile_basename1);
  base::FilePath profile_path2 =
      temp_dir_.GetPath().AppendASCII(profile_basename2);
  base::FilePath profile_path3 =
      temp_dir_.GetPath().AppendASCII(profile_basename3);

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileCreated(testing::NotNull()))
      .Times(testing::AtLeast(1));
  EXPECT_CALL(mock_observer, OnProfileInitialized(testing::NotNull()))
      .Times(testing::AtLeast(1));
  CreateProfileAsync(profile_manager, profile_path1, &mock_observer);
  content::RunAllTasksUntilIdle();

  // Create the other profiles, but don't load them. Assign a fake avatar icon
  // to ensure that profiles in the profile attributes storage are sorted by the
  // profile name, and not randomly by the avatar name.
  ProfileAttributesStorage& storage =
      profile_manager->GetProfileAttributesStorage();
  ProfileAttributesInitParams params2;
  params2.profile_path = profile_path2;
  params2.profile_name = ASCIIToUTF16(profile_basename2);
  params2.gaia_id = GaiaId("23456");
  params2.user_name = ASCIIToUTF16(profile_basename2);
  params2.is_consented_primary_account = true;
  params2.icon_index = 1;
  storage.AddProfile(std::move(params2));
  ProfileAttributesInitParams params3;
  params3.profile_path = profile_path3;
  params3.profile_name = ASCIIToUTF16(profile_basename3);
  params3.gaia_id = GaiaId("34567");
  params3.user_name = ASCIIToUTF16(profile_basename3);
  params3.is_consented_primary_account = true;
  params3.icon_index = 2;
  storage.AddProfile(std::move(params3));

  content::RunAllTasksUntilIdle();

  EXPECT_EQ(1u, profile_manager->GetLoadedProfiles().size());
  EXPECT_EQ(3u, storage.GetNumberOfProfiles());

  // Set the active profile.
  PrefService* local_state = TestingBrowserProcess::GetGlobal()->local_state();
  local_state->SetString(prefs::kProfileLastUsed,
                         profile_path1.BaseName().MaybeAsASCII());

  // Delete the active profile, Profile1.
  // This will post a CreateProfileAsync message, that tries to load Profile2,
  // which checks that the profile is not being deleted, and then calls back
  // FinishDeletingProfile for Profile1.
  // Try to break this flow by setting the active profile to Profile2 in the
  // middle (so after the first posted message), and trying to delete Profile2,
  // so that the ProfileManager has to look for a different profile to load.
  profile_manager->GetDeleteProfileHelper().MaybeScheduleProfileForDeletion(
      profile_path1, base::DoNothing(),
      ProfileMetrics::DELETE_PROFILE_USER_MANAGER);
  local_state->SetString(prefs::kProfileLastUsed,
                         profile_path2.BaseName().MaybeAsASCII());
  profile_manager->GetDeleteProfileHelper().MaybeScheduleProfileForDeletion(
      profile_path2, base::DoNothing(),
      ProfileMetrics::DELETE_PROFILE_USER_MANAGER);
  content::RunAllTasksUntilIdle();

  EXPECT_EQ(profile_path3, profile_manager->GetLastUsedProfile()->GetPath());
  EXPECT_EQ(profile_basename3, local_state->GetString(prefs::kProfileLastUsed));
}
#endif  // BUILDFLAG(IS_MAC)

TEST_F(ProfileManagerTest, CannotCreateProfileOutsideUserDir) {
  base::ScopedTempDir non_user_dir;
  ASSERT_TRUE(non_user_dir.CreateUniqueTempDir());

  base::FilePath dest_path = non_user_dir.GetPath();
  dest_path = dest_path.Append(FILE_PATH_LITERAL("New Profile"));

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  Profile* profile = profile_manager->GetProfile(dest_path);
  EXPECT_EQ(nullptr, profile);
}

TEST_F(ProfileManagerTest, CannotCreateProfileOutsideUserDirAsync) {
  base::ScopedTempDir non_user_dir;
  ASSERT_TRUE(non_user_dir.CreateUniqueTempDir());

  base::FilePath profile_path =
      non_user_dir.GetPath().AppendASCII("New Profile");

  ProfileManager* profile_manager = g_browser_process->profile_manager();

  MockObserver mock_observer;
  EXPECT_CALL(mock_observer, OnProfileInitialized(nullptr));

  CreateProfileAsync(profile_manager, profile_path, &mock_observer);
  content::RunAllTasksUntilIdle();
}

struct ProfileKeepAliveParam {
  ProfileKeepAliveOrigin origin;
  bool should_clear_waiting_for_first_browser_window = false;
};

constexpr ProfileKeepAliveParam params[] = {
    // Origins that clears
    // `ProfileKeepAliveOrigin::kWaitingForFirstBrowserWindow`.
    {.origin = ProfileKeepAliveOrigin::kBrowserWindow,
     .should_clear_waiting_for_first_browser_window = true},
    {.origin = ProfileKeepAliveOrigin::kProfileCreationFlow,
     .should_clear_waiting_for_first_browser_window = true},
    {.origin = ProfileKeepAliveOrigin::kProfileStatistics,
     .should_clear_waiting_for_first_browser_window = true},
    {.origin = ProfileKeepAliveOrigin::kProfilePickerView,
     .should_clear_waiting_for_first_browser_window = true},
    {.origin = ProfileKeepAliveOrigin::kWaitingForGlicView,
     .should_clear_waiting_for_first_browser_window = true},

    // Origins that do NOT clear
    // `ProfileKeepAliveOrigin::kWaitingForFirstBrowserWindow`.
    {.origin = ProfileKeepAliveOrigin::kBackgroundMode,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kOffTheRecordProfile,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kDownloadInProgress,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kClearingBrowsingData,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kAppWindow,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kBackgroundSync,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kNotification,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kPendingNotificationClickEvent,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kInFlightPushMessage,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kSessionRestore,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kChromeViewsDelegate,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kDevToolsWindow,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kWebAppPermissionDialogWindow,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kExtensionUpdater,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kPendingNotificationCloseEvent,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kFeedbackDialog,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kWebAppUpdate,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kGettingWebAppInfo,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kCrxInstaller,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kHistoryMenuBridge,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kProfileCreationSamlFlow,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kProfileDeletionProcess,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kIsolatedWebAppInstall,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kIsolatedWebAppUpdate,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kWebAppUninstall,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kOsIntegrationForceUnregistration,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kRemoteDebugging,
     .should_clear_waiting_for_first_browser_window = false},
    {.origin = ProfileKeepAliveOrigin::kHeadlessCommand,
     .should_clear_waiting_for_first_browser_window = false},
};

std::string ParamsToTestSuffix(
    const ::testing::TestParamInfo<ProfileKeepAliveParam>& info) {
  std::stringstream stream;
  stream << info.param.origin;
  return stream.str();
}

class ProfileManagerTestWithParam
    : public ProfileManagerTest,
      public testing::WithParamInterface<ProfileKeepAliveParam> {
 public:
  ProfileManagerTestWithParam() {
    scoped_feature_list_.InitWithFeatures(
        {features::kDestroySystemProfiles,
         features::kDestroyProfileOnBrowserClose},
        {});
  }

 private:
  base::test::ScopedFeatureList scoped_feature_list_;
};

TEST_P(ProfileManagerTestWithParam, ScopedProfileKeepAlive) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();

  base::FilePath dest_path = temp_dir_.GetPath().AppendASCII("New Profile");
  Profile* profile = profile_manager->GetProfile(dest_path);

  // Starts with a kWaitingForFirstBrowserWindow ref.
  EXPECT_THAT(profile_manager->GetProfileInfoByPath(dest_path)->keep_alives,
              ::testing::ElementsAre(std::pair<ProfileKeepAliveOrigin, int>(
                  ProfileKeepAliveOrigin::kWaitingForFirstBrowserWindow, 1)));

  {
    // Set |profile| refcount to 1. If this added keep alive has an origin that
    // should remove the `kWaitingForFirstBrowserWindow` keep alive, it will
    // cause the profile to get deleted at the end of this block.
    ScopedProfileKeepAlive keep_alive(profile, GetParam().origin);

    // We added a keep alive that should be part of the list of keep alives.
    // Whether `kWaitingForFirstBrowserWindow` ref is removed depends on
    // `GetParam().should_clear_waiting_for_first_browser_window`.
    EXPECT_THAT(
        profile_manager->GetProfileInfoByPath(dest_path)->keep_alives,
        ::testing::UnorderedElementsAre(
            std::pair<ProfileKeepAliveOrigin, int>(
                ProfileKeepAliveOrigin::kWaitingForFirstBrowserWindow,
                GetParam().should_clear_waiting_for_first_browser_window ? 0
                                                                         : 1),
            std::pair<ProfileKeepAliveOrigin, int>(GetParam().origin, 1)));
  }

  base::RunLoop().RunUntilIdle();
  if (GetParam().should_clear_waiting_for_first_browser_window) {
#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
    // Profile* should've been destroyed by now.
    EXPECT_EQ(nullptr, profile_manager->GetProfileByPath(dest_path));
#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_CHROMEOS)
  } else {
    // `profile` is still valid since `kWaitingForFirstBrowserWindow` was not
    // cleared.
    EXPECT_EQ(profile, profile_manager->GetProfileByPath(dest_path));
  }
}

INSTANTIATE_TEST_SUITE_P(,
                         ProfileManagerTestWithParam,
                         testing::ValuesIn(params),
                         &ParamsToTestSuffix);

TEST_F(ProfileManagerTest, ProfileCountRecordedAtProfileInit) {
  using base::Bucket;
  using base::BucketsAre;

  base::HistogramTester histogram_tester;
  const std::string kHistogramName = "Profile.NumberOfProfilesAtProfileInit";
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  base::FilePath dest_path = temp_dir_.GetPath();

  base::FilePath path_1 = dest_path.Append(FILE_PATH_LITERAL("Profile 1"));
  profile_manager->GetProfile(path_1);
  EXPECT_THAT(histogram_tester.GetAllSamples(kHistogramName),
              BucketsAre(Bucket(1, 1)));

  Profile* profile_2 = profile_manager->GetProfile(
      dest_path.Append(FILE_PATH_LITERAL("Profile 2")));
  EXPECT_EQ(profile_manager->GetNumberOfProfiles(), 2u);
  EXPECT_THAT(histogram_tester.GetAllSamples(kHistogramName),
              BucketsAre(Bucket(1, 1), Bucket(2, 1)));

  // Incognito profile should not affect the count.
  EXPECT_TRUE(profile_2->GetPrimaryOTRProfile(/*create_if_needed=*/true));
  EXPECT_THAT(histogram_tester.GetAllSamples(kHistogramName),
              BucketsAre(Bucket(1, 1), Bucket(2, 1)));

#if !BUILDFLAG(IS_ANDROID)
  // Delete one profile to decrement the count.
  profile_manager->GetDeleteProfileHelper().MaybeScheduleProfileForDeletion(
      path_1, base::DoNothing(), ProfileMetrics::DELETE_PROFILE_USER_MANAGER);
  content::RunAllTasksUntilIdle();

  profile_manager->GetProfile(dest_path.Append(FILE_PATH_LITERAL("Profile 3")));
  EXPECT_THAT(histogram_tester.GetAllSamples(kHistogramName),
              BucketsAre(Bucket(1, 1), Bucket(2, 2)));
#endif  // !BUILDFLAG(IS_ANDROID)
}
