// 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 "remoting/base/gaia_oauth_client.h"

#include "base/callback_helpers.h"
#include "base/logging.h"

namespace {
const int kMaxGaiaRetries = 3;
}  // namespace

namespace remoting {

GaiaOAuthClient::GaiaOAuthClient(
    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter)
    : gaia_oauth_client_(url_request_context_getter.get()) {}

GaiaOAuthClient::~GaiaOAuthClient() = default;

void GaiaOAuthClient::GetCredentialsFromAuthCode(
    const gaia::OAuthClientInfo& oauth_client_info,
    const std::string& auth_code,
    bool need_user_email,
    CompletionCallback on_done) {
  if (!on_done_.is_null()) {
    pending_requests_.push(
        Request(oauth_client_info, auth_code, need_user_email, on_done));
    return;
  }

  need_user_email_ = need_user_email;
  on_done_ = on_done;
  // Map the authorization code to refresh and access tokens.
  gaia_oauth_client_.GetTokensFromAuthCode(oauth_client_info, auth_code,
                                           kMaxGaiaRetries, this);
}

void GaiaOAuthClient::OnGetTokensResponse(const std::string& refresh_token,
                                          const std::string& access_token,
                                          int expires_in_seconds) {
  refresh_token_ = refresh_token;
  if (need_user_email_) {
    // Get the email corresponding to the access token.
    gaia_oauth_client_.GetUserEmail(access_token, kMaxGaiaRetries, this);
  } else {
    SendResponse("", refresh_token_);
  }
}

void GaiaOAuthClient::OnRefreshTokenResponse(const std::string& access_token,
                                             int expires_in_seconds) {
  // We never request a refresh token, so this call is not expected.
  NOTREACHED();
}

void GaiaOAuthClient::SendResponse(const std::string& user_email,
                                   const std::string& refresh_token) {
  base::ResetAndReturn(&on_done_).Run(user_email, refresh_token);

  // Process the next request in the queue.
  if (pending_requests_.size()) {
    Request request = pending_requests_.front();
    pending_requests_.pop();
    // GetCredentialsFromAuthCode is asynchronous, so it's safe to call it here.
    GetCredentialsFromAuthCode(request.oauth_client_info, request.auth_code,
                               request.need_user_email, request.on_done);
  }
}

void GaiaOAuthClient::OnGetUserEmailResponse(const std::string& user_email) {
  SendResponse(user_email, refresh_token_);
}

void GaiaOAuthClient::OnOAuthError() {
  SendResponse("", "");
}

void GaiaOAuthClient::OnNetworkError(int response_code) {
  SendResponse("", "");
}

GaiaOAuthClient::Request::Request(
    const gaia::OAuthClientInfo& oauth_client_info,
    const std::string& auth_code,
    bool need_user_email,
    CompletionCallback on_done) {
  this->oauth_client_info = oauth_client_info;
  this->auth_code = auth_code;
  this->need_user_email = need_user_email;
  this->on_done = on_done;
}

GaiaOAuthClient::Request::Request(const Request& other) = default;

GaiaOAuthClient::Request::~Request() = default;

}  // namespace remoting
