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

#include "google_apis/gaia/oauth2_token_service.h"

#include <stdint.h>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_access_token_manager.h"
#include "google_apis/gaia/oauth2_token_service_delegate.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"

OAuth2TokenService::RequestImpl::RequestImpl(
    const CoreAccountId& account_id,
    OAuth2TokenService::Consumer* consumer)
    : account_id_(account_id), consumer_(consumer) {}

OAuth2TokenService::RequestImpl::~RequestImpl() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}

CoreAccountId OAuth2TokenService::RequestImpl::GetAccountId() const {
  return account_id_;
}

std::string OAuth2TokenService::RequestImpl::GetConsumerId() const {
  return consumer_->id();
}

void OAuth2TokenService::RequestImpl::InformConsumer(
    const GoogleServiceAuthError& error,
    const OAuth2AccessTokenConsumer::TokenResponse& token_response) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (error.state() == GoogleServiceAuthError::NONE)
    consumer_->OnGetTokenSuccess(this, token_response);
  else
    consumer_->OnGetTokenFailure(this, error);
}

OAuth2TokenService::Request::Request() {
}

OAuth2TokenService::Request::~Request() {
}

OAuth2TokenService::Consumer::Consumer(const std::string& id)
    : id_(id) {}

OAuth2TokenService::Consumer::~Consumer() {
}

OAuth2TokenService::OAuth2TokenService(
    std::unique_ptr<OAuth2TokenServiceDelegate> delegate)
    : delegate_(std::move(delegate)), all_credentials_loaded_(false) {
  DCHECK(delegate_);
  AddObserver(this);
  token_manager_ =
      std::make_unique<OAuth2AccessTokenManager>(this, delegate_.get());
}

OAuth2TokenService::~OAuth2TokenService() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  RemoveObserver(this);
}

OAuth2TokenServiceDelegate* OAuth2TokenService::GetDelegate() {
  return delegate_.get();
}

const OAuth2TokenServiceDelegate* OAuth2TokenService::GetDelegate() const {
  return delegate_.get();
}

const base::ObserverList<AccessTokenDiagnosticsObserver, true>::Unchecked&
OAuth2TokenService::GetAccessTokenDiagnosticsObservers() {
  return token_manager_->diagnostics_observer_list_;
}

int OAuth2TokenService::GetTokenCacheCount() {
  return token_manager_->token_cache().size();
}

void OAuth2TokenService::AddObserver(OAuth2TokenServiceObserver* observer) {
  delegate_->AddObserver(observer);
}

void OAuth2TokenService::RemoveObserver(OAuth2TokenServiceObserver* observer) {
  delegate_->RemoveObserver(observer);
}

void OAuth2TokenService::AddAccessTokenDiagnosticsObserver(
    AccessTokenDiagnosticsObserver* observer) {
  token_manager_->AddDiagnosticsObserver(observer);
}

void OAuth2TokenService::RemoveAccessTokenDiagnosticsObserver(
    AccessTokenDiagnosticsObserver* observer) {
  token_manager_->RemoveDiagnosticsObserver(observer);
}

std::unique_ptr<OAuth2TokenService::Request>
OAuth2TokenService::StartRequestForMultilogin(
    const CoreAccountId& account_id,
    OAuth2TokenService::Consumer* consumer) {
  const std::string refresh_token =
      delegate_->GetTokenForMultilogin(account_id);
  if (refresh_token.empty()) {
    // If we can't get refresh token from the delegate, start request for access
    // token.
    OAuth2TokenService::ScopeSet scopes;
    scopes.insert(GaiaConstants::kOAuth1LoginScope);
    return StartRequest(account_id, scopes, consumer);
  }
  std::unique_ptr<RequestImpl> request(new RequestImpl(account_id, consumer));
  // Create token response from token. Expiration time and id token do not
  // matter and should not be accessed.
  OAuth2AccessTokenConsumer::TokenResponse token_response(
      refresh_token, base::Time(), std::string());
  // If we can get refresh token from the delegate, inform cosumer right away.
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(&RequestImpl::InformConsumer, request.get()->AsWeakPtr(),
                     GoogleServiceAuthError(GoogleServiceAuthError::NONE),
                     token_response));
  return std::move(request);
}

std::unique_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest(
    const CoreAccountId& account_id,
    const OAuth2TokenService::ScopeSet& scopes,
    OAuth2TokenService::Consumer* consumer) {
  return token_manager_->StartRequest(account_id, scopes, consumer);
}

std::unique_ptr<OAuth2TokenService::Request>
OAuth2TokenService::StartRequestForClient(
    const CoreAccountId& account_id,
    const std::string& client_id,
    const std::string& client_secret,
    const OAuth2TokenService::ScopeSet& scopes,
    OAuth2TokenService::Consumer* consumer) {
  return token_manager_->StartRequestForClient(account_id, client_id,
                                               client_secret, scopes, consumer);
}

std::unique_ptr<OAuth2TokenService::Request>
OAuth2TokenService::StartRequestWithContext(
    const CoreAccountId& account_id,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    const ScopeSet& scopes,
    Consumer* consumer) {
  return token_manager_->StartRequestWithContext(account_id, url_loader_factory,
                                                 scopes, consumer);
}

void OAuth2TokenService::FetchOAuth2Token(
    RequestImpl* request,
    const CoreAccountId& account_id,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    const std::string& client_id,
    const std::string& client_secret,
    const ScopeSet& scopes) {
  token_manager_->FetchOAuth2Token(request, account_id, url_loader_factory,
                                   client_id, client_secret, scopes);
}

bool OAuth2TokenService::AreAllCredentialsLoaded() const {
  return all_credentials_loaded_;
}

std::vector<CoreAccountId> OAuth2TokenService::GetAccounts() const {
  if (!AreAllCredentialsLoaded())
    return std::vector<CoreAccountId>();

  return delegate_->GetAccounts();
}

bool OAuth2TokenService::RefreshTokenIsAvailable(
    const CoreAccountId& account_id) const {
  return delegate_->RefreshTokenIsAvailable(account_id);
}

bool OAuth2TokenService::RefreshTokenHasError(
    const CoreAccountId& account_id) const {
  return GetAuthError(account_id) != GoogleServiceAuthError::AuthErrorNone();
}

GoogleServiceAuthError OAuth2TokenService::GetAuthError(
    const CoreAccountId& account_id) const {
  GoogleServiceAuthError error = delegate_->GetAuthError(account_id);
  DCHECK(!error.IsTransientError());
  return error;
}

void OAuth2TokenService::InvalidateAccessToken(
    const CoreAccountId& account_id,
    const ScopeSet& scopes,
    const std::string& access_token) {
  token_manager_->InvalidateAccessToken(account_id, scopes, access_token);
}

void OAuth2TokenService::InvalidateTokenForMultilogin(
    const CoreAccountId& failed_account,
    const std::string& token) {
  OAuth2TokenService::ScopeSet scopes;
  scopes.insert(GaiaConstants::kOAuth1LoginScope);
  // Remove from cache. This will have no effect on desktop since token is a
  // refresh token and is not in cache.
  InvalidateAccessToken(failed_account, scopes, token);
  // For desktop refresh tokens can be invalidated directly in delegate. This
  // will have no effect on mobile.
  delegate_->InvalidateTokenForMultilogin(failed_account);
}

void OAuth2TokenService::InvalidateAccessTokenImpl(
    const CoreAccountId& account_id,
    const std::string& client_id,
    const ScopeSet& scopes,
    const std::string& access_token) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  token_manager_->InvalidateAccessTokenImpl(account_id, client_id, scopes,
                                            access_token);
}

void OAuth2TokenService::OnRefreshTokensLoaded() {
  all_credentials_loaded_ = true;
}

void OAuth2TokenService::UpdateAuthError(const CoreAccountId& account_id,
                                         const GoogleServiceAuthError& error) {
  delegate_->UpdateAuthError(account_id, error);
}

void OAuth2TokenService::RegisterTokenResponse(
    const std::string& client_id,
    const CoreAccountId& account_id,
    const ScopeSet& scopes,
    const OAuth2AccessTokenConsumer::TokenResponse& token_response) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  token_manager_->RegisterTokenResponse(client_id, account_id, scopes,
                                        token_response);
}

void OAuth2TokenService::ClearCache() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  token_manager_->ClearCache();
}

void OAuth2TokenService::ClearCacheForAccount(const CoreAccountId& account_id) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  token_manager_->ClearCacheForAccount(account_id);
}

void OAuth2TokenService::CancelAllRequests() {
  token_manager_->CancelAllRequests();
}

void OAuth2TokenService::CancelRequestsForAccount(
    const CoreAccountId& account_id) {
  token_manager_->CancelRequestsForAccount(account_id);
}

void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing(
    int max_retries) {
  token_manager_->set_max_authorization_token_fetch_retries_for_testing(
      max_retries);
}

size_t OAuth2TokenService::GetNumPendingRequestsForTesting(
    const std::string& client_id,
    const CoreAccountId& account_id,
    const ScopeSet& scopes) const {
  return token_manager_->GetNumPendingRequestsForTesting(client_id, account_id,
                                                         scopes);
}
