// Copyright 2017 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 "base/bind.h"
#include "base/run_loop.h"
#include "base/test/scoped_task_environment.h"
#include "build/build_config.h"
#include "components/signin/core/browser/account_info.h"
#include "services/identity/identity_service.h"
#include "services/identity/public/cpp/account_state.h"
#include "services/identity/public/cpp/identity_test_environment.h"
#include "services/identity/public/cpp/scope_set.h"
#include "services/identity/public/mojom/account.mojom.h"
#include "services/identity/public/mojom/constants.mojom.h"
#include "services/identity/public/mojom/identity_accessor.mojom.h"
#include "services/service_manager/public/cpp/binder_registry.h"
#include "services/service_manager/public/cpp/test/test_connector_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace identity {

const char kTestGaiaId[] = "gaia_id_for_me_dummy.com";
const char kTestEmail[] = "me@dummy.com";
const char kTestAccessToken[] = "access_token";

class IdentityAccessorImplTest : public testing::Test {
 public:
  IdentityAccessorImplTest()
      : identity_test_environment_(),
        service_(
            identity_test_environment_.identity_manager(),
            test_connector_factory_.RegisterInstance(mojom::kServiceName)) {}

  void TearDown() override {
    // Explicitly destruct IdentityAccessorImpl so that it doesn't outlive its
    // dependencies.
    ResetIdentityAccessorImpl();

    // Wait for the IdentityAccessorImpl to be notified of disconnection and
    // destroy itself.
    base::RunLoop().RunUntilIdle();
  }

  void OnReceivedPrimaryAccountInfo(
      base::RepeatingClosure quit_closure,
      const base::Optional<AccountInfo>& account_info,
      const AccountState& account_state) {
    primary_account_info_ = account_info;
    primary_account_state_ = account_state;
    quit_closure.Run();
  }

  void OnPrimaryAccountAvailable(base::RepeatingClosure quit_closure,
                                 AccountInfo* caller_account_info,
                                 AccountState* caller_account_state,
                                 const AccountInfo& account_info,
                                 const AccountState& account_state) {
    *caller_account_info = account_info;
    *caller_account_state = account_state;
    quit_closure.Run();
  }

  void OnGotAccounts(base::RepeatingClosure quit_closure,
                     std::vector<mojom::AccountPtr>* output,
                     std::vector<mojom::AccountPtr> accounts) {
    *output = std::move(accounts);
    quit_closure.Run();
  }

  void OnReceivedAccessToken(base::RepeatingClosure quit_closure,
                             const base::Optional<std::string>& access_token,
                             base::Time expiration_time,
                             const GoogleServiceAuthError& error) {
    access_token_ = access_token;
    access_token_error_ = error;
    quit_closure.Run();
  }

 protected:
  mojom::IdentityAccessor* GetIdentityAccessorImpl() {
    if (!identity_accessor_) {
      test_connector_factory_.GetDefaultConnector()->BindInterface(
          mojom::kServiceName, &identity_accessor_);
    }
    return identity_accessor_.get();
  }

  void ResetIdentityAccessorImpl() { identity_accessor_.reset(); }

  void FlushIdentityAccessorImplForTesting() {
    GetIdentityAccessorImpl();
    identity_accessor_.FlushForTesting();
  }

  void SetIdentityAccessorImplConnectionErrorHandler(
      base::RepeatingClosure handler) {
    GetIdentityAccessorImpl();
    identity_accessor_.set_connection_error_handler(handler);
  }

  base::test::ScopedTaskEnvironment task_environemnt_;

  mojom::IdentityAccessorPtr identity_accessor_;
  base::Optional<AccountInfo> primary_account_info_;
  AccountState primary_account_state_;
  base::Optional<AccountInfo> account_info_from_gaia_id_;
  AccountState account_state_from_gaia_id_;
  base::Optional<std::string> access_token_;
  GoogleServiceAuthError access_token_error_;

  IdentityTestEnvironment* identity_test_environment() {
    return &identity_test_environment_;
  }

 private:
  identity::IdentityTestEnvironment identity_test_environment_;
  service_manager::TestConnectorFactory test_connector_factory_;
  IdentityService service_;

  DISALLOW_COPY_AND_ASSIGN(IdentityAccessorImplTest);
};

// Check that the primary account info is null if not signed in.
TEST_F(IdentityAccessorImplTest, GetPrimaryAccountInfoNotSignedIn) {
  base::RunLoop run_loop;
  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
      base::Unretained(this), run_loop.QuitClosure()));
  run_loop.Run();
  EXPECT_FALSE(primary_account_info_);
}

// Check that the primary account info has expected values if signed in without
// a refresh token available.
TEST_F(IdentityAccessorImplTest, GetPrimaryAccountInfoSignedInNoRefreshToken) {
  std::string primary_account_id =
      identity_test_environment()->SetPrimaryAccount(kTestEmail).account_id;

  base::RunLoop run_loop;
  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
      base::Unretained(this), run_loop.QuitClosure()));
  run_loop.Run();

  EXPECT_TRUE(primary_account_info_);
  EXPECT_EQ(primary_account_id, primary_account_info_->account_id);
  EXPECT_EQ(kTestGaiaId, primary_account_info_->gaia);
  EXPECT_EQ(kTestEmail, primary_account_info_->email);
  EXPECT_FALSE(primary_account_state_.has_refresh_token);
  EXPECT_TRUE(primary_account_state_.is_primary_account);
}

// Check that the primary account info has expected values if signed in with a
// refresh token available.
TEST_F(IdentityAccessorImplTest, GetPrimaryAccountInfoSignedInRefreshToken) {
  std::string primary_account_id = identity_test_environment()
                                       ->MakePrimaryAccountAvailable(kTestEmail)
                                       .account_id;

  base::RunLoop run_loop;
  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
      base::Unretained(this), run_loop.QuitClosure()));
  run_loop.Run();

  EXPECT_TRUE(primary_account_info_);
  EXPECT_EQ(primary_account_id, primary_account_info_->account_id);
  EXPECT_EQ(kTestGaiaId, primary_account_info_->gaia);
  EXPECT_EQ(kTestEmail, primary_account_info_->email);
  EXPECT_TRUE(primary_account_state_.has_refresh_token);
  EXPECT_TRUE(primary_account_state_.is_primary_account);
}

// Check that GetPrimaryAccountWhenAvailable() returns immediately in the
// case where the primary account is available when the call is received.
TEST_F(IdentityAccessorImplTest, GetPrimaryAccountWhenAvailableSignedIn) {
  std::string primary_account_id = identity_test_environment()
                                       ->MakePrimaryAccountAvailable(kTestEmail)
                                       .account_id;

  AccountInfo account_info;
  AccountState account_state;
  base::RunLoop run_loop;
  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
      base::Unretained(this), run_loop.QuitClosure(),
      base::Unretained(&account_info), base::Unretained(&account_state)));
  run_loop.Run();

  EXPECT_EQ(primary_account_id, account_info.account_id);
  EXPECT_EQ(kTestGaiaId, account_info.gaia);
  EXPECT_EQ(kTestEmail, account_info.email);
  EXPECT_TRUE(account_state.has_refresh_token);
  EXPECT_TRUE(account_state.is_primary_account);
}

// Check that GetPrimaryAccountWhenAvailable() returns the expected account
// info in the case where the primary account is made available *after* the
// call is received.
TEST_F(IdentityAccessorImplTest, GetPrimaryAccountWhenAvailableSignInLater) {
  AccountInfo account_info;
  AccountState account_state;

  base::RunLoop run_loop;
  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
      base::Unretained(this), run_loop.QuitClosure(),
      base::Unretained(&account_info), base::Unretained(&account_state)));

  // Verify that the primary account info is not currently available (this also
  // serves to ensure that the preceding call has been received by the
  // IdentityAccessor before proceeding).
  base::RunLoop run_loop2;
  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
      base::Unretained(this), run_loop2.QuitClosure()));
  run_loop2.Run();
  EXPECT_FALSE(primary_account_info_);

  // Make the primary account available and check that the callback is invoked
  // as expected.
  std::string primary_account_id = identity_test_environment()
                                       ->MakePrimaryAccountAvailable(kTestEmail)
                                       .account_id;
  run_loop.Run();

  EXPECT_EQ(primary_account_id, account_info.account_id);
  EXPECT_EQ(kTestGaiaId, account_info.gaia);
  EXPECT_EQ(kTestEmail, account_info.email);
  EXPECT_TRUE(account_state.has_refresh_token);
  EXPECT_TRUE(account_state.is_primary_account);
}

// Check that GetPrimaryAccountWhenAvailable() returns the expected account
// info in the case where signin is done before the call is received but the
// refresh token is made available only *after* the call is received.
TEST_F(IdentityAccessorImplTest,
       GetPrimaryAccountWhenAvailableTokenAvailableLater) {
  AccountInfo account_info;
  AccountState account_state;

  // Sign in, but don't set the refresh token yet.
  std::string primary_account_id =
      identity_test_environment()->SetPrimaryAccount(kTestEmail).account_id;
  base::RunLoop run_loop;
  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
      base::Unretained(this), run_loop.QuitClosure(),
      base::Unretained(&account_info), base::Unretained(&account_state)));

  // Verify that the primary account info is present, but that the primary
  // account is not yet considered available (this also
  // serves to ensure that the preceding call has been received by the
  // IdentityAccessor before proceeding).
  base::RunLoop run_loop2;
  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
      base::Unretained(this), run_loop2.QuitClosure()));
  run_loop2.Run();

  EXPECT_TRUE(primary_account_info_);
  EXPECT_EQ(primary_account_id, primary_account_info_->account_id);
  EXPECT_TRUE(account_info.account_id.empty());

  // Set the refresh token and check that the callback is invoked as expected
  // (i.e., the primary account is now considered available).
  identity_test_environment()->SetRefreshTokenForPrimaryAccount();
  run_loop.Run();

  EXPECT_EQ(primary_account_id, account_info.account_id);
  EXPECT_EQ(kTestGaiaId, account_info.gaia);
  EXPECT_EQ(kTestEmail, account_info.email);
  EXPECT_TRUE(account_state.has_refresh_token);
  EXPECT_TRUE(account_state.is_primary_account);
}

// Check that GetPrimaryAccountWhenAvailable() returns the expected account info
// in the case where the token is available before the call is received but the
// account is made authenticated only *after* the call is received. This test is
// relevant only on non-ChromeOS platforms, as the flow being tested here is not
// possible on ChromeOS.
#if !defined(OS_CHROMEOS)
TEST_F(IdentityAccessorImplTest,
       GetPrimaryAccountWhenAvailableAuthenticationAvailableLater) {
  AccountInfo account_info;
  AccountState account_state;

  // Set the refresh token, but don't sign in yet.
  std::string account_id_to_use =
      identity_test_environment()->MakeAccountAvailable(kTestEmail).account_id;
  identity_test_environment()->SetRefreshTokenForAccount(account_id_to_use);

  base::RunLoop run_loop;
  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
      base::Unretained(this), run_loop.QuitClosure(),
      base::Unretained(&account_info), base::Unretained(&account_state)));

  // Sign the user in and check that the callback is invoked as expected (i.e.,
  // the primary account is now considered available).
  std::string primary_account_id =
      identity_test_environment()->SetPrimaryAccount(kTestEmail).account_id;

  run_loop.Run();

  EXPECT_EQ(primary_account_id, account_info.account_id);
  EXPECT_EQ(kTestGaiaId, account_info.gaia);
  EXPECT_EQ(kTestEmail, account_info.email);
  EXPECT_TRUE(account_state.has_refresh_token);
  EXPECT_TRUE(account_state.is_primary_account);
}
#endif

// Check that GetPrimaryAccountWhenAvailable() returns the expected account
// info to all callers in the case where the primary account is made available
// after multiple overlapping calls have been received.
TEST_F(IdentityAccessorImplTest,
       GetPrimaryAccountWhenAvailableOverlappingCalls) {
  AccountInfo account_info1;
  AccountState account_state1;
  base::RunLoop run_loop;
  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
      base::Unretained(this), run_loop.QuitClosure(),
      base::Unretained(&account_info1), base::Unretained(&account_state1)));

  AccountInfo account_info2;
  AccountState account_state2;
  base::RunLoop run_loop2;
  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
      base::Unretained(this), run_loop2.QuitClosure(),
      base::Unretained(&account_info2), base::Unretained(&account_state2)));

  // Verify that the primary account info is not currently available (this also
  // serves to ensure that the preceding call has been received by the
  // IdentityAccessor before proceeding).
  base::RunLoop run_loop3;
  GetIdentityAccessorImpl()->GetPrimaryAccountInfo(base::BindRepeating(
      &IdentityAccessorImplTest::OnReceivedPrimaryAccountInfo,
      base::Unretained(this), run_loop3.QuitClosure()));
  run_loop3.Run();
  EXPECT_FALSE(primary_account_info_);

  // Make the primary account available and check that the callbacks are invoked
  // as expected.
  std::string primary_account_id = identity_test_environment()
                                       ->MakePrimaryAccountAvailable(kTestEmail)
                                       .account_id;

  run_loop.Run();
  run_loop2.Run();

  EXPECT_EQ(primary_account_id, account_info1.account_id);
  EXPECT_EQ(kTestGaiaId, account_info1.gaia);
  EXPECT_EQ(kTestEmail, account_info1.email);
  EXPECT_TRUE(account_state1.has_refresh_token);
  EXPECT_TRUE(account_state1.is_primary_account);

  EXPECT_EQ(primary_account_id, account_info2.account_id);
  EXPECT_EQ(kTestGaiaId, account_info2.gaia);
  EXPECT_EQ(kTestEmail, account_info2.email);
  EXPECT_TRUE(account_state2.has_refresh_token);
  EXPECT_TRUE(account_state2.is_primary_account);
}

// Check that GetPrimaryAccountWhenAvailable() doesn't return the account as
// available if the refresh token has an auth error.
TEST_F(IdentityAccessorImplTest,
       GetPrimaryAccountWhenAvailableRefreshTokenHasAuthError) {
  std::string primary_account_id = identity_test_environment()
                                       ->MakePrimaryAccountAvailable(kTestEmail)
                                       .account_id;
  identity_test_environment()->UpdatePersistentErrorOfRefreshTokenForAccount(
      primary_account_id,
      GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));

  AccountInfo account_info;
  AccountState account_state;
  base::RunLoop run_loop;
  GetIdentityAccessorImpl()->GetPrimaryAccountWhenAvailable(base::BindRepeating(
      &IdentityAccessorImplTest::OnPrimaryAccountAvailable,
      base::Unretained(this), run_loop.QuitClosure(),
      base::Unretained(&account_info), base::Unretained(&account_state)));

  // Flush the IdentityAccessor and check that the callback didn't fire.
  FlushIdentityAccessorImplForTesting();
  EXPECT_TRUE(account_info.account_id.empty());

  // Clear the auth error, update credentials, and check that the callback
  // fires.
  identity_test_environment()->UpdatePersistentErrorOfRefreshTokenForAccount(
      primary_account_id, GoogleServiceAuthError());
  identity_test_environment()->SetRefreshTokenForPrimaryAccount();
  run_loop.Run();

  EXPECT_EQ(primary_account_id, account_info.account_id);
  EXPECT_EQ(kTestGaiaId, account_info.gaia);
  EXPECT_EQ(kTestEmail, account_info.email);
  EXPECT_TRUE(account_state.has_refresh_token);
  EXPECT_TRUE(account_state.is_primary_account);
}

// Check that the expected error is received if requesting an access token when
// not signed in.
TEST_F(IdentityAccessorImplTest, GetAccessTokenNotSignedIn) {
  base::RunLoop run_loop;
  GetIdentityAccessorImpl()->GetAccessToken(
      kTestGaiaId, ScopeSet(), "dummy_consumer",
      base::BindRepeating(&IdentityAccessorImplTest::OnReceivedAccessToken,
                          base::Unretained(this), run_loop.QuitClosure()));
  run_loop.Run();
  EXPECT_FALSE(access_token_);
  EXPECT_EQ(GoogleServiceAuthError::State::USER_NOT_SIGNED_UP,
            access_token_error_.state());
}

// Check that the expected access token is received if requesting an access
// token when signed in.
TEST_F(IdentityAccessorImplTest, GetAccessTokenSignedIn) {
  std::string primary_account_id = identity_test_environment()
                                       ->MakePrimaryAccountAvailable(kTestEmail)
                                       .account_id;
  base::RunLoop run_loop;
  GetIdentityAccessorImpl()->GetAccessToken(
      primary_account_id, ScopeSet(), "dummy_consumer",
      base::BindRepeating(&IdentityAccessorImplTest::OnReceivedAccessToken,
                          base::Unretained(this), run_loop.QuitClosure()));
  identity_test_environment()
      ->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
          kTestAccessToken, base::Time::Max());
  run_loop.Run();

  EXPECT_TRUE(access_token_);
  EXPECT_EQ(kTestAccessToken, access_token_.value());
  EXPECT_EQ(GoogleServiceAuthError::State::NONE, access_token_error_.state());
}

}  // namespace identity
