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

// This class keeps track of the currently-active profiles in the runtime.

#ifndef CHROME_BROWSER_PROFILES_PROFILE_MANAGER_H_
#define CHROME_BROWSER_PROFILES_PROFILE_MANAGER_H_

#include <stddef.h>

#include <list>
#include <memory>
#include <vector>

#include "base/containers/hash_tables.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread_checker.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/profiles/profile_shortcut_manager.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "chrome/common/buildflags.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"

class ProfileAttributesStorage;
class ProfileInfoCache;

class ProfileManager : public content::NotificationObserver,
                       public Profile::Delegate {
 public:
  typedef base::RepeatingCallback<void(Profile*, Profile::CreateStatus)>
      CreateCallback;
  typedef base::OnceCallback<void(Profile*)> ProfileLoadedCallback;

  explicit ProfileManager(const base::FilePath& user_data_dir);
  ~ProfileManager() override;

#if BUILDFLAG(ENABLE_SESSION_SERVICE)
  // Invokes SessionServiceFactory::ShutdownForProfile() for all profiles.
  static void ShutdownSessionServices();
#endif

  // Physically remove deleted profile directories from disk.
  static void NukeDeletedProfilesFromDisk();

  // Same as instance method but provides the default user_data_dir as well.
  // If the Profile is going to be used to open a new window then consider using
  // GetLastUsedProfileAllowedByPolicy() instead.
  static Profile* GetLastUsedProfile();

  // Same as GetLastUsedProfile() but returns the incognito Profile if
  // incognito mode is forced. This should be used if the last used Profile
  // will be used to open new browser windows.
  static Profile* GetLastUsedProfileAllowedByPolicy();

  // Helper function that returns true if incognito mode is forced for |profile|
  // (normal mode is not available for browsing).
  static bool IncognitoModeForced(Profile* profile);

  // Same as instance method but provides the default user_data_dir as well.
  static std::vector<Profile*> GetLastOpenedProfiles();

  // Get the profile for the user which created the current session.
  // Note that in case of a guest account this will return a 'suitable' profile.
  // This function is temporary and will soon be moved to ash. As such avoid
  // using it at all cost.
  // TODO(skuhne): Move into ash's new user management function.
  static Profile* GetPrimaryUserProfile();

  // Get the profile for the currently active user.
  // Note that in case of a guest account this will return a 'suitable' profile.
  // This function is temporary and will soon be moved to ash. As such avoid
  // using it at all cost.
  // TODO(skuhne): Move into ash's new user management function.
  static Profile* GetActiveUserProfile();

  // Load and return the initial profile for browser. On ChromeOS, this returns
  // either the sign-in profile or the active user profile depending on whether
  // browser is started normally or is restarted after crash. On other
  // platforms, this returns the default profile.
  static Profile* CreateInitialProfile();

  // Returns a profile for a specific profile directory within the user data
  // dir. This will return an existing profile it had already been created,
  // otherwise it will create and manage it.
  // Because this method might synchronously create a new profile, it should
  // only be called for the initial profile or in tests, where blocking is
  // acceptable. Returns null if creation of the new profile fails.
  // TODO(bauerb): Migrate calls from other code to GetProfileByPath(), then
  // make this method private.
  Profile* GetProfile(const base::FilePath& profile_dir);

  // Returns total number of profiles available on this machine.
  size_t GetNumberOfProfiles();

  // Asynchronously loads an existing profile given its |profile_name| within
  // the user data directory, optionally in |incognito| mode. The |callback|
  // will be called with the Profile when it has been loaded, or with a nullptr
  // otherwise. Should be called on the UI thread.
  // Unlike CreateProfileAsync this will not create a profile if one doesn't
  // already exist on disk
  // Returns true if the profile exists, but the final loaded profile will come
  // as part of the callback.
  bool LoadProfile(const std::string& profile_name,
                   bool incognito,
                   ProfileLoadedCallback callback);
  bool LoadProfileByPath(const base::FilePath& profile_path,
                         bool incognito,
                         ProfileLoadedCallback callback);

  // Explicit asynchronous creation of a profile located at |profile_path|.
  // If the profile has already been created then callback is called
  // immediately. Should be called on the UI thread.
  void CreateProfileAsync(const base::FilePath& profile_path,
                          const CreateCallback& callback,
                          const base::string16& name,
                          const std::string& icon_url,
                          const std::string& supervised_user_id);

  // Returns true if the profile pointer is known to point to an existing
  // profile.
  bool IsValidProfile(const void* profile);

  // Returns the directory where the first created profile is stored,
  // relative to the user data directory currently in use.
  base::FilePath GetInitialProfileDir();

  // Get the Profile last used (the Profile to which owns the most recently
  // focused window) with this Chrome build. If no signed profile has been
  // stored in Local State, hand back the Default profile.
  Profile* GetLastUsedProfile(const base::FilePath& user_data_dir);

  // Get the path of the last used profile, or if that's undefined, the default
  // profile.
  base::FilePath GetLastUsedProfileDir(const base::FilePath& user_data_dir);

  // Get the name of the last used profile, or if that's undefined, the default
  // profile.
  std::string GetLastUsedProfileName();

  // Get the Profiles which are currently open, i.e. have open browsers or were
  // open the last time Chrome was running. Profiles that fail to initialize are
  // skipped. The Profiles appear in the order they were opened. The last used
  // profile will be on the list if it is initialized successfully, but its
  // index on the list will depend on when it was opened (it is not necessarily
  // the last one).
  std::vector<Profile*> GetLastOpenedProfiles(
      const base::FilePath& user_data_dir);

  // Returns created and fully initialized profiles. Note, profiles order is NOT
  // guaranteed to be related with the creation order.
  std::vector<Profile*> GetLoadedProfiles() const;

  // If a profile with the given path is currently managed by this object and
  // fully initialized, return a pointer to the corresponding Profile object;
  // otherwise return null.
  Profile* GetProfileByPath(const base::FilePath& path) const;

  // Creates a new profile in the next available multiprofile directory.
  // Directories are named "profile_1", "profile_2", etc., in sequence of
  // creation. (Because directories can be removed, however, it may be the case
  // that at some point the list of numbered profiles is not continuous.)
  // |callback| may be invoked multiple times (for CREATE_STATUS_INITIALIZED
  // and CREATE_STATUS_CREATED) so binding parameters with bind::Passed() is
  // prohibited. Returns the file path to the profile that will be created
  // asynchronously.
  static base::FilePath CreateMultiProfileAsync(
      const base::string16& name,
      const std::string& icon_url,
      const CreateCallback& callback,
      const std::string& supervised_user_id);

  // Returns the full path to be used for guest profiles.
  static base::FilePath GetGuestProfilePath();

  // Returns the full path to be used for system profiles.
  static base::FilePath GetSystemProfilePath();

  // Get the path of the next profile directory and increment the internal
  // count.
  // Lack of side effects:
  // This function doesn't actually create the directory or touch the file
  // system.
  base::FilePath GenerateNextProfileDirectoryPath();

  // Returns a ProfileAttributesStorage object which can be used to get
  // information about profiles without having to load them from disk.
  ProfileAttributesStorage& GetProfileAttributesStorage();

  // Returns a ProfileShortcut Manager that enables the caller to create
  // profile specfic desktop shortcuts.
  ProfileShortcutManager* profile_shortcut_manager();

#if !defined(OS_ANDROID)
  // Less strict version of ScheduleProfileForDeletion(), silently exits if
  // profile is either scheduling or marked for deletion.
  void MaybeScheduleProfileForDeletion(
      const base::FilePath& profile_dir,
      ProfileLoadedCallback callback,
      ProfileMetrics::ProfileDelete deletion_source);

  // Schedules the profile at the given path to be deleted on shutdown. If we're
  // deleting the last profile, a new one will be created in its place, and in
  // that case the callback will be called when profile creation is complete.
  void ScheduleProfileForDeletion(const base::FilePath& profile_dir,
                                  ProfileLoadedCallback callback);
#endif

  // Autoloads profiles if they are running background apps.
  void AutoloadProfiles();

  // Checks if any ephemeral profiles are left behind (e.g. because of a browser
  // crash) and schedule them for deletion.
  void CleanUpEphemeralProfiles();

  // Checks if files of deleted profiles are left behind (e.g. because of a
  // browser crash) and delete them in case they still exist.
  void CleanUpDeletedProfiles();

  // Initializes user prefs of |profile|. This includes profile name and
  // avatar values.
  void InitProfileUserPrefs(Profile* profile);

  // Register and add testing profile to the ProfileManager. Use ONLY in tests.
  // This allows the creation of Profiles outside of the standard creation path
  // for testing. If |addToStorage|, adds to ProfileAttributesStorage as well.
  // If |start_deferred_task_runners|, starts the deferred task runners.
  // Use ONLY in tests.
  void RegisterTestingProfile(Profile* profile,
                              bool addToStorage,
                              bool start_deferred_task_runners);

  const base::FilePath& user_data_dir() const { return user_data_dir_; }

  // For ChromeOS, determines if the user has logged in to a real profile.
  bool IsLoggedIn() const { return logged_in_; }

  // content::NotificationObserver implementation.
  void Observe(int type,
               const content::NotificationSource& source,
               const content::NotificationDetails& details) override;

  // Profile::Delegate implementation:
  void OnProfileCreated(Profile* profile,
                        bool success,
                        bool is_new_profile) override;

 protected:
  // Does final initial actions.
  virtual void DoFinalInit(Profile* profile, bool go_off_the_record);
  virtual void DoFinalInitForServices(Profile* profile, bool go_off_the_record);
  virtual void DoFinalInitLogging(Profile* profile);

  // Creates a new profile by calling into the profile's profile creation
  // method. Virtual so that unittests can return a TestingProfile instead
  // of the Profile's result. Returns null if creation fails.
  virtual Profile* CreateProfileHelper(const base::FilePath& path);

  // Creates a new profile asynchronously by calling into the profile's
  // asynchronous profile creation method. Virtual so that unittests can return
  // a TestingProfile instead of the Profile's result.
  virtual Profile* CreateProfileAsyncHelper(const base::FilePath& path,
                                            Delegate* delegate);

 private:
  friend class TestingProfileManager;
  FRIEND_TEST_ALL_PREFIXES(ProfileManagerBrowserTest, DeleteAllProfiles);
  FRIEND_TEST_ALL_PREFIXES(ProfileManagerBrowserTest, SwitchToProfile);

  // This struct contains information about profiles which are being loaded or
  // were loaded.
  struct ProfileInfo {
    ProfileInfo(Profile* profile, bool created);

    ~ProfileInfo();

    std::unique_ptr<Profile> profile;
    // Whether profile has been fully loaded (created and initialized).
    bool created;
    // List of callbacks to run when profile initialization is done. Note, when
    // profile is fully loaded this vector will be empty.
    std::vector<CreateCallback> callbacks;

   private:
    DISALLOW_COPY_AND_ASSIGN(ProfileInfo);
  };

  // Returns the profile of the active user and / or the off the record profile
  // if needed. This adds the profile to the ProfileManager if it doesn't
  // already exist. The method will return NULL if the profile doesn't exist
  // and we can't create it.
  // The profile used can be overridden by using --login-profile on cros.
  Profile* GetActiveUserOrOffTheRecordProfileFromPath(
      const base::FilePath& user_data_dir);

  // Adds a pre-existing Profile object to the set managed by this
  // ProfileManager. This ProfileManager takes ownership of the Profile.
  // The Profile should not already be managed by this ProfileManager.
  // Returns true if the profile was added, false otherwise.
  bool AddProfile(Profile* profile);

  // Synchronously creates and returns a profile. This handles both the full
  // creation and adds it to the set managed by this ProfileManager. Returns
  // null if creation fails.
  Profile* CreateAndInitializeProfile(const base::FilePath& profile_dir);

#if !defined(OS_ANDROID)
  // Continues the scheduled profile deletion after closing all the profile's
  // browsers tabs. Creates a new profile if the profile to be deleted is the
  // last non-supervised profile. In the Mac, loads the next non-supervised
  // profile if the profile to be deleted is the active profile.
  void EnsureActiveProfileExistsBeforeDeletion(
      ProfileLoadedCallback callback,
      const base::FilePath& profile_dir);

  // Schedules the profile at the given path to be deleted on shutdown,
  // and marks the new profile as active.
  void FinishDeletingProfile(const base::FilePath& profile_dir,
                             const base::FilePath& new_active_profile_dir);
  void OnLoadProfileForProfileDeletion(const base::FilePath& profile_dir,
                                       Profile* profile);
#endif

  // Registers profile with given info. Returns pointer to created ProfileInfo
  // entry.
  ProfileInfo* RegisterProfile(Profile* profile, bool created);

  // Returns ProfileInfo associated with given |path|, registered earlier with
  // RegisterProfile.
  ProfileInfo* GetProfileInfoByPath(const base::FilePath& path) const;

  // Returns a registered profile. In contrast to GetProfileByPath(), this will
  // also return a profile that is not fully initialized yet, so this method
  // should be used carefully.
  Profile* GetProfileByPathInternal(const base::FilePath& path) const;

  // Returns a ProfileInfoCache object which can be used to get information
  // about profiles without having to load them from disk.
  // Deprecated, use GetProfileAttributesStorage() instead.
  ProfileInfoCache& GetProfileInfoCache();

  // Adds |profile| to the profile attributes storage if it hasn't been added
  // yet.
  void AddProfileToStorage(Profile* profile);

  // Apply settings for profiles created by the system rather than users: The
  // (desktop) Guest User profile and (desktop) System Profile.
  void SetNonPersonalProfilePrefs(Profile* profile);

  // For ChromeOS, determines if profile should be otr.
  bool ShouldGoOffTheRecord(Profile* profile);

  void RunCallbacks(const std::vector<CreateCallback>& callbacks,
                    Profile* profile,
                    Profile::CreateStatus status);

#if !defined(OS_ANDROID)
  // Updates the last active user of the current session.
  // On Chrome OS updating this user will have no effect since when browser is
  // restored after crash there's another preference that is taken into account.
  // See kLastActiveUser in UserManagerBase.
  void UpdateLastUser(Profile* last_active);

  class BrowserListObserver : public ::BrowserListObserver {
   public:
    explicit BrowserListObserver(ProfileManager* manager);
    ~BrowserListObserver() override;

    // ::BrowserListObserver implementation.
    void OnBrowserAdded(Browser* browser) override;
    void OnBrowserRemoved(Browser* browser) override;
    void OnBrowserSetLastActive(Browser* browser) override;

   private:
    ProfileManager* profile_manager_;
    DISALLOW_COPY_AND_ASSIGN(BrowserListObserver);
  };

  // If the |loaded_profile| has been loaded successfully (according to
  // |status|) and isn't already scheduled for deletion, then finishes adding
  // |profile_to_delete_dir| to the queue of profiles to be deleted, and updates
  // the kProfileLastUsed preference based on
  // |last_non_supervised_profile_path|.
  void OnNewActiveProfileLoaded(
      const base::FilePath& profile_to_delete_path,
      const base::FilePath& last_non_supervised_profile_path,
      ProfileLoadedCallback callback,
      Profile* loaded_profile,
      Profile::CreateStatus status);

  // Schedules the forced ephemeral profile at the given path to be deleted on
  // shutdown. New profiles will not be created.
  void ScheduleForcedEphemeralProfileForDeletion(
      const base::FilePath& profile_dir);
#endif  // !defined(OS_ANDROID)

  // Object to cache various information about profiles. Contains information
  // about every profile which has been created for this instance of Chrome,
  // if it has not been explicitly deleted. It must be destroyed after
  // |profiles_info_| because ~ProfileInfo can trigger a chain of events leading
  // to an access to this member.
  std::unique_ptr<ProfileInfoCache> profile_info_cache_;

  content::NotificationRegistrar registrar_;

  // The path to the user data directory (DIR_USER_DATA).
  const base::FilePath user_data_dir_;

  // Indicates that a user has logged in and that the profile specified
  // in the --login-profile command line argument should be used as the
  // default.
  bool logged_in_;

#if !defined(OS_ANDROID)
  BrowserListObserver browser_list_observer_;
#endif  // !defined(OS_ANDROID)

  // Maps profile path to ProfileInfo (if profile has been created). Use
  // RegisterProfile() to add into this map. This map owns all loaded profile
  // objects in a running instance of Chrome.
  using ProfilesInfoMap =
      std::map<base::FilePath, std::unique_ptr<ProfileInfo>>;
  ProfilesInfoMap profiles_info_;

  // Manages the process of creating, deleteing and updating Desktop shortcuts.
  std::unique_ptr<ProfileShortcutManager> profile_shortcut_manager_;

  // For keeping track of the last active profiles.
  std::map<Profile*, int> browser_counts_;
  // On startup we launch the active profiles in the order they became active
  // during the last run. This is why they are kept in a list, not in a set.
  std::vector<Profile*> active_profiles_;
  bool closing_all_browsers_;

  // TODO(chrome/browser/profiles/OWNERS): Usage of this in profile_manager.cc
  // should likely be turned into DCHECK_CURRENTLY_ON(BrowserThread::UI) for
  // consistency with surrounding code in the same file but that wasn't trivial
  // enough to do as part of the mass refactor CL which introduced
  // |thread_checker_|, ref. https://codereview.chromium.org/2907253003/#msg37.
  THREAD_CHECKER(thread_checker_);

  DISALLOW_COPY_AND_ASSIGN(ProfileManager);
};

// Same as the ProfileManager, but doesn't initialize some services of the
// profile. This one is useful in unittests.
class ProfileManagerWithoutInit : public ProfileManager {
 public:
  explicit ProfileManagerWithoutInit(const base::FilePath& user_data_dir);

 protected:
  void DoFinalInitForServices(Profile*, bool) override {}
  void DoFinalInitLogging(Profile*) override {}
};

#endif  // CHROME_BROWSER_PROFILES_PROFILE_MANAGER_H_
