// Copyright 2017 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.

#ifndef SERVICES_IDENTITY_PUBLIC_CPP_IDENTITY_MANAGER_H_
#define SERVICES_IDENTITY_PUBLIC_CPP_IDENTITY_MANAGER_H_

#include "base/observer_list.h"
#include "components/signin/core/browser/account_info.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/gaia_cookie_manager_service.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_internals_util.h"
#include "components/signin/core/browser/signin_manager_base.h"
#include "components/signin/core/browser/signin_metrics.h"
#include "services/identity/public/cpp/access_token_fetcher.h"
#include "services/identity/public/cpp/accounts_mutator.h"
#include "services/identity/public/cpp/scope_set.h"

#if !defined(OS_CHROMEOS)
#include "components/signin/core/browser/signin_manager.h"
#endif

// Necessary to declare this class as a friend.
namespace arc {
class ArcTermsOfServiceDefaultNegotiatorTest;
}

// Necessary to declare these classes as friends.
namespace chromeos {
class ChromeSessionManager;
class UserSessionManager;
}

// Necessary to declare this class as a friend.
namespace file_manager {
class MultiProfileFilesAppBrowserTest;
}

namespace network {
class SharedURLLoaderFactory;
}

// Necessary to declare these classes as friends.
class ArcSupportHostTest;
class MultiProfileDownloadNotificationTest;

namespace identity {

class PrimaryAccountMutator;
enum class ClearPrimaryAccountPolicy;

// Gives access to information about the user's Google identities. See
// ./README.md for detailed documentation.
class IdentityManager : public SigninManagerBase::Observer,
                        public OAuth2TokenService::DiagnosticsObserver,
                        public OAuth2TokenService::Observer,
                        public signin_internals_util::SigninDiagnosticsObserver,
                        public GaiaCookieManagerService::Observer {
 public:
  class Observer {
   public:
    Observer() = default;
    virtual ~Observer() = default;

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

    // Called when an account becomes the user's primary account.
    // This method is not called during a reauth.
    virtual void OnPrimaryAccountSet(const AccountInfo& primary_account_info) {}

    // Called when an account becomes the user's primary account using the
    // legacy workflow (non-DICE). If access to the password is not required,
    // it is preferred to instead override OnPrimaryAccountSet() which will
    // also be called at the same time.
    virtual void OnPrimaryAccountSetWithPassword(
        const AccountInfo& primary_account_info,
        const std::string& password) {}

    // Called when when the user moves from having a primary account to no
    // longer having a primary account.
    virtual void OnPrimaryAccountCleared(
        const AccountInfo& previous_primary_account_info) {}

    // Called when the user attempts but fails to set their primary
    // account. |error| gives the reason for the failure.
    virtual void OnPrimaryAccountSigninFailed(
        const GoogleServiceAuthError& error) {}

    // Called when a new refresh token is associated with |account_info|.
    // NOTE: On a signin event, the ordering of this callback wrt the
    // OnPrimaryAccountSet() callback is undefined. If you as a client are
    // interested in both callbacks, PrimaryAccountAccessTokenFetcher will
    // likely meet your needs. Otherwise, if this lack of ordering is
    // problematic for your use case, please contact blundell@chromium.org.
    virtual void OnRefreshTokenUpdatedForAccount(
        const AccountInfo& account_info) {}

    // Called when the refresh token previously associated with |account_id|
    // has been removed. At the time that this callback is invoked, there is
    // no longer guaranteed to be any AccountInfo associated with
    // |account_id|.
    // NOTE: It is not guaranteed that a call to
    // OnRefreshTokenUpdatedForAccount() has previously occurred for this
    // account due to corner cases.
    // TODO(https://crbug.com/884731): Eliminate these corner cases.
    // NOTE: On a signout event, the ordering of this callback wrt the
    // OnPrimaryAccountCleared() callback is undefined.If this lack of ordering
    // is problematic for your use case, please contact blundell@chromium.org.
    virtual void OnRefreshTokenRemovedForAccount(
        const std::string& account_id) {}

    // Called after refresh tokens are loaded.
    // CAVEAT: On ChromeOS, this callback is not invoked during
    // startup in all cases. See https://crbug.com/749535, which
    // details the cases where it's not invoked.
    virtual void OnRefreshTokensLoaded() {}

    // Called whenever the list of Gaia accounts in the cookie jar has changed.
    // |accounts| is ordered by the order of the accounts in the cookie.
    virtual void OnAccountsInCookieUpdated(
        const std::vector<AccountInfo>& accounts) {}

    // Called before a batch of refresh token state changes is started.
    virtual void OnStartBatchOfRefreshTokenStateChanges() {}

    // Called after a batch of refresh token state chagnes is completed.
    virtual void OnEndBatchOfRefreshTokenStateChanges() {}
  };

  // Observer interface for classes that want to monitor status of various
  // requests. Mostly useful in tests and debugging contexts (e.g., WebUI).
  class DiagnosticsObserver {
   public:
    DiagnosticsObserver() = default;
    virtual ~DiagnosticsObserver() = default;

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

    // Called when receiving request for access token.
    virtual void OnAccessTokenRequested(const std::string& account_id,
                                        const std::string& consumer_id,
                                        const identity::ScopeSet& scopes) {}

    // Called on credentials and signin related changes.
    virtual void NotifySigninValueChanged(
        const signin_internals_util::TimedSigninStatusField& field,
        const std::string& value) {}
  };

  IdentityManager(
      SigninManagerBase* signin_manager,
      ProfileOAuth2TokenService* token_service,
      AccountTrackerService* account_tracker_service,
      GaiaCookieManagerService* gaia_cookie_manager_service,
      std::unique_ptr<PrimaryAccountMutator> primary_account_mutator);
  ~IdentityManager() override;

  // Provides access to the extended information of the user's primary account.
  // Returns an empty struct if no such info is available, either because there
  // is no primary account or because the extended information for the primary
  // account has been removed (this happens when the refresh token is revoked,
  // for example).
  AccountInfo GetPrimaryAccountInfo() const;

  // Provides access to the account ID of the user's primary account. Note that
  // this may return a valid string even in cases where GetPrimaryAccountInfo()
  // returns an empty struct, as the extended information for the primary
  // account is removed on certain events (e.g., when its refresh token is
  // revoked).
  const std::string& GetPrimaryAccountId() const;

  // Returns whether the primary account is available. Simple convenience
  // wrapper over checking whether GetPrimaryAccountId() returns a non-empty
  // string.
  bool HasPrimaryAccount() const;

  // Provides access to the latest cached information of all accounts that have
  // refresh tokens.
  // NOTE: The accounts should not be assumed to be in any particular order; in
  // particular, they are not guaranteed to be in the order in which the
  // refresh tokens were added.
  std::vector<AccountInfo> GetAccountsWithRefreshTokens() const;

  // Provides access to the latest cached information of all accounts that are
  // present in the Gaia cookie in the cookie jar, ordered by their order in
  // the cookie. If the cached state is known to be stale by the underlying
  // implementation, a call to this method will trigger an internal update and
  // subsequent invocation of
  // IdentityManager::Observer::OnAccountsInCookieJarChanged().
  // NOTE: The information of whether the cached state is known to be stale by
  // the underlying implementation is not currently exposed. The design for
  // exposing it if necessary is tracked by https://crbug.com/859882. If the
  // lack of this exposure is a blocker for you in using this API, contact
  // blundell@chromium.org.
  std::vector<AccountInfo> GetAccountsInCookieJar() const;

  // Returns true if a refresh token exists for |account_id|.
  bool HasAccountWithRefreshToken(const std::string& account_id) const;

  // Returns true if (a) a refresh token exists for |account_id|, and (b) the
  // refresh token is in a persistent error state (defined as
  // GoogleServiceAuthError::IsPersistentError() returning true for the error
  // returned by GetErrorStateOfRefreshTokenForAccount(account_id)).
  bool HasAccountWithRefreshTokenInPersistentErrorState(
      const std::string& account_id) const;

  // Returns the error state of the refresh token associated with |account_id|.
  // In particular: Returns GoogleServiceAuthError::AuthErrorNone() if either
  // (a) no refresh token exists for |account_id|, or (b) the refresh token is
  // not in a persistent error state. Otherwise, returns the last persistent
  // error that was detected when using the refresh token.
  GoogleServiceAuthError GetErrorStateOfRefreshTokenForAccount(
      const std::string& account_id) const;

  // Returns true if (a) the primary account exists, and (b) a refresh token
  // exists for the primary account.
  bool HasPrimaryAccountWithRefreshToken() const;

  // Looks up and returns information for account with given |account_id|. If
  // the account cannot be found, return an empty optional. This is equivalent
  // to searching on the vector returned by GetAccountsWithRefreshTokens() but
  // without allocating memory for the vector.
  base::Optional<AccountInfo>
  FindAccountInfoForAccountWithRefreshTokenByAccountId(
      const std::string& account_id) const;

  // Looks up and returns information for account with given |email_address|. If
  // the account cannot be found, return an empty optional. This is equivalent
  // to searching on the vector returned by GetAccountsWithRefreshTokens() but
  // without allocating memory for the vector.
  base::Optional<AccountInfo>
  FindAccountInfoForAccountWithRefreshTokenByEmailAddress(
      const std::string& email_address) const;

  // Looks up and returns information for account with given |gaia_id|. If the
  // account cannot be found, return an empty optional. This is equivalent to
  // searching on the vector returned by GetAccountsWithRefreshTokens() but
  // without allocating memory for the vector.
  base::Optional<AccountInfo> FindAccountInfoForAccountWithRefreshTokenByGaiaId(
      const std::string& gaia_id) const;

  // Creates an AccessTokenFetcher given the passed-in information.
  std::unique_ptr<AccessTokenFetcher> CreateAccessTokenFetcherForAccount(
      const std::string& account_id,
      const std::string& oauth_consumer_name,
      const identity::ScopeSet& scopes,
      AccessTokenFetcher::TokenCallback callback,
      AccessTokenFetcher::Mode mode);

  // Creates an AccessTokenFetcher given the passed-in information, allowing
  // to specify a custom |url_loader_factory| as well.
  std::unique_ptr<AccessTokenFetcher> CreateAccessTokenFetcherForAccount(
      const std::string& account_id,
      const std::string& oauth_consumer_name,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
      const identity::ScopeSet& scopes,
      AccessTokenFetcher::TokenCallback callback,
      AccessTokenFetcher::Mode mode);

  // If an entry exists in the Identity Service's cache corresponding to the
  // given information, removes that entry; in this case, the next access token
  // request for |account_id| and |scopes| will fetch a new token from the
  // network. Otherwise, is a no-op.
  void RemoveAccessTokenFromCache(const std::string& account_id,
                                  const identity::ScopeSet& scopes,
                                  const std::string& access_token);

  // Returns pointer to the object used to change the signed-in state of the
  // primary account, if supported on the current platform. Otherwise, returns
  // null.
  PrimaryAccountMutator* GetPrimaryAccountMutator();

  // Returns pointer to the object used to seed accounts and mutate state of
  // accounts' refresh tokens. Guaranteed to be non-null.
  AccountsMutator* GetAccountsMutator();

  // Methods to register or remove observers.
  void AddObserver(Observer* observer);
  void RemoveObserver(Observer* observer);
  void AddDiagnosticsObserver(DiagnosticsObserver* observer);
  void RemoveDiagnosticsObserver(DiagnosticsObserver* observer);

 private:
  // These test helpers need to use some of the private methods below.
  friend AccountInfo SetPrimaryAccount(IdentityManager* identity_manager,
                                       const std::string& email);
  friend void SetRefreshTokenForPrimaryAccount(
      IdentityManager* identity_manager,
      const std::string* token);
  friend void SetInvalidRefreshTokenForPrimaryAccount(
      IdentityManager* identity_manager);
  friend void RemoveRefreshTokenForPrimaryAccount(
      IdentityManager* identity_manager);
  friend AccountInfo MakePrimaryAccountAvailable(
      IdentityManager* identity_manager,
      const std::string& email);
  friend void ClearPrimaryAccount(IdentityManager* identity_manager,
                                  ClearPrimaryAccountPolicy policy);
  friend AccountInfo MakeAccountAvailable(IdentityManager* identity_manager,
                                          const std::string& email);
  friend void SetRefreshTokenForAccount(IdentityManager* identity_manager,
                                        const std::string& account_id,
                                        const std::string* token);
  friend void SetInvalidRefreshTokenForAccount(
      IdentityManager* identity_manager,
      const std::string& account_id);
  friend void RemoveRefreshTokenForAccount(IdentityManager* identity_manager,
                                           const std::string& account_id);
  friend void UpdateAccountInfoForAccount(IdentityManager* identity_manager,
                                          AccountInfo account_info);
  friend void UpdatePersistentErrorOfRefreshTokenForAccount(
      IdentityManager* identity_manager,
      const std::string& account_id,
      const GoogleServiceAuthError& auth_error);

  friend MultiProfileDownloadNotificationTest;
  friend file_manager::MultiProfileFilesAppBrowserTest;

  // These clients needs to call SetPrimaryAccountSynchronously().
  friend ArcSupportHostTest;
  friend arc::ArcTermsOfServiceDefaultNegotiatorTest;
  friend chromeos::ChromeSessionManager;
  friend chromeos::UserSessionManager;

  // Private getters used for testing only (i.e. see identity_test_utils.h).
  SigninManagerBase* GetSigninManager();
  ProfileOAuth2TokenService* GetTokenService();
  AccountTrackerService* GetAccountTrackerService();

  // Sets the primary account info synchronously with both the IdentityManager
  // and its backing SigninManager/ProfileOAuth2TokenService instances.
  // Prefer using the methods in identity_test_{environment, utils}.h to using
  // this method directly.
  void SetPrimaryAccountSynchronouslyForTests(const std::string& gaia_id,
                                              const std::string& email_address,
                                              const std::string& refresh_token);

  // Sets the primary account info synchronously with both the IdentityManager
  // and its backing SigninManager instance. If |refresh_token| is not empty,
  // sets the refresh token with the backing ProfileOAuth2TokenService
  // instance. This method should not be used directly; it exists only to serve
  // one legacy use case at this point.
  // TODO(https://crbug.com/814787): Eliminate the need for this method.
  void SetPrimaryAccountSynchronously(const std::string& gaia_id,
                                      const std::string& email_address,
                                      const std::string& refresh_token);

  // Populates and returns an AccountInfo object corresponding to |account_id|,
  // which must be an account with a refresh token.
  AccountInfo GetAccountInfoForAccountWithRefreshToken(
      const std::string& account_id) const;

  // SigninManagerBase::Observer:
  void GoogleSigninSucceeded(const AccountInfo& account_info) override;
  void GoogleSigninSucceededWithPassword(const AccountInfo& account_info,
                                         const std::string& password) override;
  void GoogleSignedOut(const AccountInfo& account_info) override;
  void GoogleSigninFailed(const GoogleServiceAuthError& error) override;

  // OAuth2TokenService::Observer:
  void OnRefreshTokenAvailable(const std::string& account_id) override;
  void OnRefreshTokenRevoked(const std::string& account_id) override;
  void OnRefreshTokensLoaded() override;
  void OnStartBatchChanges() override;
  void OnEndBatchChanges() override;

  // GaiaCookieManagerService::Observer:
  void OnGaiaAccountsInCookieUpdated(
      const std::vector<gaia::ListedAccount>& accounts,
      const std::vector<gaia::ListedAccount>& signed_out_accounts,
      const GoogleServiceAuthError& error) override;

  // OAuth2TokenService::DiagnosticsObserver:
  void OnAccessTokenRequested(
      const std::string& account_id,
      const std::string& consumer_id,
      const OAuth2TokenService::ScopeSet& scopes) override;

  void NotifySigninValueChanged(
      const signin_internals_util::TimedSigninStatusField& field,
      const std::string& value) override;

  // Backing signin classes. NOTE: We strive to limit synchronous access to
  // these classes in the IdentityManager implementation, as all such
  // synchronous access will become impossible when IdentityManager is
  // backed by the Identity Service.
  SigninManagerBase* signin_manager_;
  ProfileOAuth2TokenService* token_service_;
  AccountTrackerService* account_tracker_service_;
  GaiaCookieManagerService* gaia_cookie_manager_service_;

  // PrimaryAccountMutator instance. May be null if mutation of the primary
  // account state is not supported on the current platform.
  std::unique_ptr<PrimaryAccountMutator> primary_account_mutator_;

  // AccountsMutator instance. Guaranteed to be non-null, as this
  // functionality is supported on all platforms.
  AccountsMutator accounts_mutator_;

  // Lists of observers.
  // Makes sure lists are empty on destruction.
  base::ObserverList<Observer, true>::Unchecked observer_list_;
  base::ObserverList<DiagnosticsObserver, true>::Unchecked
      diagnostics_observer_list_;

  DISALLOW_COPY_AND_ASSIGN(IdentityManager);
};

}  // namespace identity

#endif  // SERVICES_IDENTITY_PUBLIC_CPP_IDENTITY_MANAGER_H_
