// Copyright 2014 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_request.h"

#include <set>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/location.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "base/threading/thread_task_runner_handle.h"
#include "google_apis/gaia/fake_oauth2_token_service.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_token_service.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

const char kAccessToken[] = "access_token";
const char kAccountIdString[] = "test_user@gmail.com";
const char kScope[] = "SCOPE";

class TestingOAuth2TokenServiceConsumer : public OAuth2TokenService::Consumer {
 public:
  TestingOAuth2TokenServiceConsumer();
  ~TestingOAuth2TokenServiceConsumer() override;

  void OnGetTokenSuccess(
      const OAuth2TokenService::Request* request,
      const OAuth2AccessTokenConsumer::TokenResponse& token_response) override;
  void OnGetTokenFailure(const OAuth2TokenService::Request* request,
                         const GoogleServiceAuthError& error) override;

  int num_get_token_success_;
  int num_get_token_failure_;
  std::string last_token_;
  std::string last_id_token_;
  GoogleServiceAuthError last_error_;
};

TestingOAuth2TokenServiceConsumer::TestingOAuth2TokenServiceConsumer()
    : OAuth2TokenService::Consumer("test"),
      num_get_token_success_(0),
      num_get_token_failure_(0),
      last_error_(GoogleServiceAuthError::AuthErrorNone()) {
}

TestingOAuth2TokenServiceConsumer::~TestingOAuth2TokenServiceConsumer() {
}

void TestingOAuth2TokenServiceConsumer::OnGetTokenSuccess(
    const OAuth2TokenService::Request* request,
    const OAuth2AccessTokenConsumer::TokenResponse& token_response) {
  last_token_ = token_response.access_token;
  last_id_token_ = token_response.id_token;
  ++num_get_token_success_;
}

void TestingOAuth2TokenServiceConsumer::OnGetTokenFailure(
    const OAuth2TokenService::Request* request,
    const GoogleServiceAuthError& error) {
  last_error_ = error;
  ++num_get_token_failure_;
}

// A mock implementation of an OAuth2TokenService.
//
// Use SetResponse to vary the response to token requests.
class MockOAuth2TokenService : public FakeOAuth2TokenService {
 public:
  MockOAuth2TokenService();
  ~MockOAuth2TokenService() override;

  void SetResponse(const GoogleServiceAuthError& error,
                   const std::string& access_token,
                   const base::Time& expiration,
                   const std::string& id_token);

  int num_invalidate_token() const { return num_invalidate_token_; }

  const std::string& last_token_invalidated() const {
    return last_token_invalidated_;
  }

 protected:
  void 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) override;

  void InvalidateAccessTokenImpl(const CoreAccountId& account_id,
                                 const std::string& client_id,
                                 const ScopeSet& scopes,
                                 const std::string& access_token) override;

 private:
  GoogleServiceAuthError response_error_;
  std::string response_access_token_;
  base::Time response_expiration_;
  std::string response_id_token_;
  int num_invalidate_token_;
  std::string last_token_invalidated_;
};

MockOAuth2TokenService::MockOAuth2TokenService()
    : response_error_(GoogleServiceAuthError::AuthErrorNone()),
      response_access_token_(kAccessToken),
      response_expiration_(base::Time::Max()),
      num_invalidate_token_(0) {
}

MockOAuth2TokenService::~MockOAuth2TokenService() {
}

void MockOAuth2TokenService::SetResponse(const GoogleServiceAuthError& error,
                                         const std::string& access_token,
                                         const base::Time& expiration,
                                         const std::string& id_token) {
  response_error_ = error;
  response_access_token_ = access_token;
  response_expiration_ = expiration;
  response_id_token_ = id_token;
}

void MockOAuth2TokenService::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) {
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::BindOnce(&OAuth2TokenService::RequestImpl::InformConsumer,
                     request->AsWeakPtr(), response_error_,
                     OAuth2AccessTokenConsumer::TokenResponse(
                         response_access_token_, response_expiration_,
                         response_id_token_)));
}

void MockOAuth2TokenService::InvalidateAccessTokenImpl(
    const CoreAccountId& account_id,
    const std::string& client_id,
    const ScopeSet& scopes,
    const std::string& access_token) {
  ++num_invalidate_token_;
  last_token_invalidated_ = access_token;
}

class OAuth2TokenServiceRequestTest : public testing::Test {
 public:
  OAuth2TokenServiceRequestTest() : kAccountId_(kAccountIdString) {}
  void SetUp() override;
  void TearDown() override;

 protected:
  class Provider : public OAuth2TokenServiceRequest::TokenServiceProvider {
   public:
    Provider(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
             OAuth2TokenService* token_service);

    scoped_refptr<base::SingleThreadTaskRunner> GetTokenServiceTaskRunner()
        override;
    OAuth2TokenService* GetTokenService() override;

   private:
    ~Provider() override;

    scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
    OAuth2TokenService* token_service_;
  };

  const CoreAccountId kAccountId_;
  base::MessageLoop ui_loop_;
  OAuth2TokenService::ScopeSet scopes_;
  std::unique_ptr<MockOAuth2TokenService> oauth2_service_;
  scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider> provider_;
  TestingOAuth2TokenServiceConsumer consumer_;
};

void OAuth2TokenServiceRequestTest::SetUp() {
  scopes_.insert(kScope);
  oauth2_service_.reset(new MockOAuth2TokenService);
  oauth2_service_->AddAccount(kAccountId_);
  provider_ =
      new Provider(base::ThreadTaskRunnerHandle::Get(), oauth2_service_.get());
}

void OAuth2TokenServiceRequestTest::TearDown() {
  // Run the loop to execute any pending tasks that may free resources.
  base::RunLoop().RunUntilIdle();
}

OAuth2TokenServiceRequestTest::Provider::Provider(
    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
    OAuth2TokenService* token_service)
    : task_runner_(task_runner), token_service_(token_service) {
}

scoped_refptr<base::SingleThreadTaskRunner>
OAuth2TokenServiceRequestTest::Provider::GetTokenServiceTaskRunner() {
  return task_runner_;
}

OAuth2TokenService* OAuth2TokenServiceRequestTest::Provider::GetTokenService() {
  return token_service_;
}

OAuth2TokenServiceRequestTest::Provider::~Provider() {
}

TEST_F(OAuth2TokenServiceRequestTest, CreateAndStart_Failure) {
  oauth2_service_->SetResponse(
      GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE),
      std::string(), base::Time(), std::string());
  std::unique_ptr<OAuth2TokenServiceRequest> request(
      OAuth2TokenServiceRequest::CreateAndStart(provider_.get(), kAccountId_,
                                                scopes_, &consumer_));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, consumer_.num_get_token_success_);
  EXPECT_EQ(1, consumer_.num_get_token_failure_);
  EXPECT_EQ(GoogleServiceAuthError::SERVICE_UNAVAILABLE,
            consumer_.last_error_.state());
  EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
}

TEST_F(OAuth2TokenServiceRequestTest, CreateAndStart_Success) {
  std::unique_ptr<OAuth2TokenServiceRequest> request(
      OAuth2TokenServiceRequest::CreateAndStart(provider_.get(), kAccountId_,
                                                scopes_, &consumer_));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(1, consumer_.num_get_token_success_);
  EXPECT_EQ(0, consumer_.num_get_token_failure_);
  EXPECT_EQ(kAccessToken, consumer_.last_token_);
  EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
}

TEST_F(OAuth2TokenServiceRequestTest,
       CreateAndStart_DestroyRequestBeforeCompletes) {
  std::unique_ptr<OAuth2TokenServiceRequest> request(
      OAuth2TokenServiceRequest::CreateAndStart(provider_.get(), kAccountId_,
                                                scopes_, &consumer_));
  request.reset();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, consumer_.num_get_token_success_);
  EXPECT_EQ(0, consumer_.num_get_token_failure_);
  EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
}

TEST_F(OAuth2TokenServiceRequestTest,
       CreateAndStart_DestroyRequestAfterCompletes) {
  std::unique_ptr<OAuth2TokenServiceRequest> request(
      OAuth2TokenServiceRequest::CreateAndStart(provider_.get(), kAccountId_,
                                                scopes_, &consumer_));
  base::RunLoop().RunUntilIdle();
  request.reset();
  EXPECT_EQ(1, consumer_.num_get_token_success_);
  EXPECT_EQ(0, consumer_.num_get_token_failure_);
  EXPECT_EQ(kAccessToken, consumer_.last_token_);
  EXPECT_EQ(0, oauth2_service_->num_invalidate_token());
}

TEST_F(OAuth2TokenServiceRequestTest, InvalidateToken) {
  OAuth2TokenServiceRequest::InvalidateToken(provider_.get(), kAccountId_,
                                             scopes_, kAccessToken);
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(0, consumer_.num_get_token_success_);
  EXPECT_EQ(0, consumer_.num_get_token_failure_);
  EXPECT_EQ(kAccessToken, oauth2_service_->last_token_invalidated());
  EXPECT_EQ(1, oauth2_service_->num_invalidate_token());
}

}  // namespace
