// Copyright 2015 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/test/access_token_fetcher.h"

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/google_api_keys.h"
#include "net/url_request/url_fetcher.h"
#include "remoting/base/url_request_context_getter.h"

namespace {
const int kMaxGetTokensRetries = 3;
const char kOauthRedirectUrl[] =
    "https://chromoting-oauth.talkgadget."
    "google.com/talkgadget/oauth/chrome-remote-desktop/dev";
}  // namespace

namespace remoting {
namespace test {

AccessTokenFetcher::AccessTokenFetcher() {
  oauth_client_info_ = {
      google_apis::GetOAuth2ClientID(google_apis::CLIENT_REMOTING),
      google_apis::GetOAuth2ClientSecret(google_apis::CLIENT_REMOTING),
      kOauthRedirectUrl};
}

AccessTokenFetcher::~AccessTokenFetcher() {
}

void AccessTokenFetcher::GetAccessTokenFromAuthCode(
    const std::string& auth_code,
    const AccessTokenCallback& callback) {
  DCHECK(!auth_code.empty());
  DCHECK(!callback.is_null());
  DCHECK(access_token_callback_.is_null());

  VLOG(2) << "Calling GetTokensFromAuthCode to exchange auth_code for token";

  access_token_.clear();
  refresh_token_.clear();
  access_token_callback_ = callback;

  // Create a new GaiaOAuthClient for each request to GAIA.
  CreateNewGaiaOAuthClientInstance();
  auth_client_->GetTokensFromAuthCode(oauth_client_info_, auth_code,
                                      kMaxGetTokensRetries,
                                      /*delegate=*/this);
}

void AccessTokenFetcher::GetAccessTokenFromRefreshToken(
    const std::string& refresh_token,
    const AccessTokenCallback& callback) {
  DCHECK(!refresh_token.empty());
  DCHECK(!callback.is_null());
  DCHECK(access_token_callback_.is_null());

  VLOG(2) << "Calling RefreshToken to generate a new access token";

  access_token_.clear();
  refresh_token_ = refresh_token;
  access_token_callback_ = callback;

  // Create a new GaiaOAuthClient for each request to GAIA.
  CreateNewGaiaOAuthClientInstance();
  auth_client_->RefreshToken(oauth_client_info_, refresh_token_,
                             /*scopes=*/std::vector<std::string>(),
                             kMaxGetTokensRetries,
                             /*delegate=*/this);
}

void AccessTokenFetcher::CreateNewGaiaOAuthClientInstance() {
  scoped_refptr<remoting::URLRequestContextGetter> request_context_getter;
  request_context_getter = new remoting::URLRequestContextGetter(
      base::ThreadTaskRunnerHandle::Get(),   // network_runner
      base::ThreadTaskRunnerHandle::Get());  // file_runner

  auth_client_.reset(new gaia::GaiaOAuthClient(request_context_getter.get()));
}

void AccessTokenFetcher::OnGetTokensResponse(const std::string& refresh_token,
                                             const std::string& access_token,
                                             int expires_in_seconds) {
  VLOG(1) << "AccessTokenFetcher::OnGetTokensResponse() Called";
  VLOG(1) << "--refresh_token: " << refresh_token;
  VLOG(1) << "--access_token: " << access_token;
  VLOG(1) << "--expires_in_seconds: " << expires_in_seconds;

  refresh_token_ = refresh_token;
  access_token_ = access_token;

  ValidateAccessToken();
}

void AccessTokenFetcher::OnRefreshTokenResponse(const std::string& access_token,
                                                int expires_in_seconds) {
  VLOG(1) << "AccessTokenFetcher::OnRefreshTokenResponse() Called";
  VLOG(1) << "--access_token: " << access_token;
  VLOG(1) << "--expires_in_seconds: " << expires_in_seconds;

  access_token_ = access_token;

  ValidateAccessToken();
}

void AccessTokenFetcher::OnGetUserEmailResponse(const std::string& user_email) {
  // This callback should not be called as we do not request the user's email.
  NOTREACHED();
}

void AccessTokenFetcher::OnGetUserIdResponse(const std::string& user_id) {
  // This callback should not be called as we do not request the user's id.
  NOTREACHED();
}

void AccessTokenFetcher::OnGetUserInfoResponse(
    std::unique_ptr<base::DictionaryValue> user_info) {
  // This callback should not be called as we do not request user info.
  NOTREACHED();
}

void AccessTokenFetcher::OnGetTokenInfoResponse(
    std::unique_ptr<base::DictionaryValue> token_info) {
  VLOG(1) << "AccessTokenFetcher::OnGetTokenInfoResponse() Called";

  std::string error_string;
  std::string error_description;

  // Check to see if the token_info we received had any errors,
  // otherwise we will assume that it is valid for our purposes.
  if (token_info->HasKey("error")) {
    token_info->GetString("error", &error_string);
    token_info->GetString("error_description", &error_description);

    LOG(ERROR) << "OnGetTokenInfoResponse returned an error. "
               << "error: " << error_string << ", "
               << "description: " << error_description;
    access_token_.clear();
    refresh_token_.clear();
  } else {
    VLOG(1) << "Access Token has been validated";
  }

  base::ResetAndReturn(&access_token_callback_)
      .Run(access_token_, refresh_token_);
}

void AccessTokenFetcher::OnOAuthError() {
  LOG(ERROR) << "AccessTokenFetcher::OnOAuthError() Called";

  access_token_.clear();
  refresh_token_.clear();

  base::ResetAndReturn(&access_token_callback_)
      .Run(access_token_, refresh_token_);
}

void AccessTokenFetcher::OnNetworkError(int response_code) {
  LOG(ERROR) << "AccessTokenFetcher::OnNetworkError() Called";
  LOG(ERROR) << "response code: " << response_code;

  access_token_.clear();
  refresh_token_.clear();

  base::ResetAndReturn(&access_token_callback_)
      .Run(access_token_, refresh_token_);
}

void AccessTokenFetcher::ValidateAccessToken() {
  VLOG(2) << "Calling GetTokenInfo to validate access token";

  // Create a new GaiaOAuthClient for each request to GAIA.
  CreateNewGaiaOAuthClientInstance();
  auth_client_->GetTokenInfo(access_token_, kMaxGetTokensRetries,
                             /*delegate=*/this);
}

}  // namespace test
}  // namespace remoting
