// Copyright 2018 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 "services/identity/public/cpp/access_token_fetcher.h"

#include <utility>

#include "base/logging.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"

namespace identity {

AccessTokenFetcher::AccessTokenFetcher(const std::string& account_id,
                                       const std::string& oauth_consumer_name,
                                       OAuth2TokenService* token_service,
                                       const identity::ScopeSet& scopes,
                                       TokenCallback callback,
                                       Mode mode)
    : AccessTokenFetcher(account_id,
                         oauth_consumer_name,
                         token_service,
                         /*url_loader_factory=*/nullptr,
                         scopes,
                         std::move(callback),
                         mode) {}

AccessTokenFetcher::AccessTokenFetcher(
    const std::string& account_id,
    const std::string& oauth_consumer_name,
    OAuth2TokenService* token_service,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    const identity::ScopeSet& scopes,
    TokenCallback callback,
    Mode mode)
    : AccessTokenFetcher(account_id,
                         /*client_id=*/std::string(),
                         /*client_secret=*/std::string(),
                         oauth_consumer_name,
                         token_service,
                         std::move(url_loader_factory),
                         scopes,
                         std::move(callback),
                         mode) {}

AccessTokenFetcher::AccessTokenFetcher(const std::string& account_id,
                                       const std::string client_id,
                                       const std::string client_secret,
                                       const std::string& oauth_consumer_name,
                                       OAuth2TokenService* token_service,
                                       const identity::ScopeSet& scopes,
                                       TokenCallback callback,
                                       Mode mode)
    : AccessTokenFetcher(account_id,
                         client_id,
                         client_secret,
                         oauth_consumer_name,
                         token_service,
                         /*url_loader_factory=*/nullptr,
                         scopes,
                         std::move(callback),
                         mode) {}

AccessTokenFetcher::AccessTokenFetcher(
    const std::string& account_id,
    const std::string client_id,
    const std::string client_secret,
    const std::string& oauth_consumer_name,
    OAuth2TokenService* token_service,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    const identity::ScopeSet& scopes,
    TokenCallback callback,
    Mode mode)
    : OAuth2TokenService::Consumer(oauth_consumer_name),
      account_id_(account_id),
      client_id_(client_id),
      client_secret_(client_secret),
      token_service_(token_service),
      url_loader_factory_(std::move(url_loader_factory)),
      scopes_(scopes),
      mode_(mode),
      callback_(std::move(callback)),
      token_service_observer_(this) {
  DCHECK(client_id_.empty() == client_secret_.empty());
  DCHECK(client_id_.empty() || !url_loader_factory);

  if (mode_ == Mode::kImmediate || IsRefreshTokenAvailable()) {
    StartAccessTokenRequest();
    return;
  }

  // Start observing the IdentityManager. This observer will be removed either
  // when a refresh token is obtained and an access token request is started or
  // when this object is destroyed.
  token_service_observer_.Add(token_service_);
}

AccessTokenFetcher::~AccessTokenFetcher() {}

bool AccessTokenFetcher::IsRefreshTokenAvailable() const {
  DCHECK_EQ(Mode::kWaitUntilRefreshTokenAvailable, mode_);

  return token_service_->RefreshTokenIsAvailable(account_id_);
}

void AccessTokenFetcher::StartAccessTokenRequest() {
  DCHECK(mode_ == Mode::kImmediate || IsRefreshTokenAvailable());

  // By the time of starting an access token request, we should no longer be
  // listening for signin-related events.
  DCHECK(!token_service_observer_.IsObserving(token_service_));

  // Note: We might get here even in cases where we know that there's no refresh
  // token. We're requesting an access token anyway, so that the token service
  // will generate an appropriate error code that we can return to the client.
  DCHECK(!access_token_request_);

  // TODO(843510): Consider making the request to ProfileOAuth2TokenService
  // asynchronously once there are no direct clients of PO2TS (i.e., PO2TS is
  // used only by this class and IdentityManager).
  if (!client_id_.empty()) {
    // Setting both the client ID/secret and the URL loader factory is not
    // currently supported.
    access_token_request_ = token_service_->StartRequestForClient(
        account_id_, client_id_, client_secret_, scopes_, this);
    return;
  }

  if (url_loader_factory_) {
    access_token_request_ = token_service_->StartRequestWithContext(
        account_id_, url_loader_factory_, scopes_, this);
    return;
  }

  access_token_request_ =
      token_service_->StartRequest(account_id_, scopes_, this);
}

void AccessTokenFetcher::OnRefreshTokenAvailable(
    const std::string& account_id) {
  DCHECK_EQ(Mode::kWaitUntilRefreshTokenAvailable, mode_);

  if (!IsRefreshTokenAvailable())
    return;

  token_service_observer_.Remove(token_service_);

  StartAccessTokenRequest();
}

void AccessTokenFetcher::OnGetTokenSuccess(
    const OAuth2TokenService::Request* request,
    const OAuth2AccessTokenConsumer::TokenResponse& token_response) {
  DCHECK_EQ(request, access_token_request_.get());
  std::unique_ptr<OAuth2TokenService::Request> request_deleter(
      std::move(access_token_request_));

  RunCallbackAndMaybeDie(
      GoogleServiceAuthError::AuthErrorNone(),
      AccessTokenInfo(token_response.access_token,
                      token_response.expiration_time, token_response.id_token));

  // Potentially dead after the above invocation; nothing to do except return.
}

void AccessTokenFetcher::OnGetTokenFailure(
    const OAuth2TokenService::Request* request,
    const GoogleServiceAuthError& error) {
  DCHECK_EQ(request, access_token_request_.get());
  std::unique_ptr<OAuth2TokenService::Request> request_deleter(
      std::move(access_token_request_));

  RunCallbackAndMaybeDie(error, AccessTokenInfo());

  // Potentially dead after the above invocation; nothing to do except return.
}

void AccessTokenFetcher::RunCallbackAndMaybeDie(
    GoogleServiceAuthError error,
    AccessTokenInfo access_token_info) {
  // Per the contract of this class, it is allowed for consumers to delete this
  // object from within the callback that is run below. Hence, it is not safe to
  // add any code below this call.
  std::move(callback_).Run(std::move(error), std::move(access_token_info));
}

}  // namespace identity
