// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/gcm_driver/gcm_account_tracker.h"

#include <map>
#include <memory>
#include <string>
#include <utility>

#include "base/memory/raw_ptr.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "components/gcm_driver/fake_gcm_driver.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "net/base/ip_endpoint.h"
#include "net/http/http_status_code.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/test/test_url_loader_factory.h"
#include "services/network/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace gcm {

namespace {

const char kEmail1[] = "account_1@me.com";
const char kEmail2[] = "account_2@me.com";

std::string MakeAccessToken(const CoreAccountId& account_id) {
  return "access_token-" + account_id.ToString();
}

GCMClient::AccountTokenInfo MakeAccountToken(const CoreAccountInfo& account) {
  GCMClient::AccountTokenInfo token_info;
  token_info.account_id = account.account_id;

  // TODO(crbug.com/40582229): This *should* be expected to be the email
  // address for the given account, but there is a bug in AccountTracker that
  // means that |token_info.email| actually gets populated with the account ID
  // by the production code. Hence the test expectation has to match what the
  // production code actually does :). If/when that bug gets fixed, this
  // function should be changed to take in the email address as well as the
  // account ID and populate this field with the email address.
  token_info.email = account.email;
  token_info.access_token = MakeAccessToken(account.account_id);
  return token_info;
}

void VerifyAccountTokens(
    const std::vector<GCMClient::AccountTokenInfo>& expected_tokens,
    const std::vector<GCMClient::AccountTokenInfo>& actual_tokens) {
  EXPECT_EQ(expected_tokens.size(), actual_tokens.size());
  for (auto expected_iter = expected_tokens.begin(),
            actual_iter = actual_tokens.begin();
       expected_iter != expected_tokens.end() &&
       actual_iter != actual_tokens.end();
       ++expected_iter, ++actual_iter) {
    EXPECT_EQ(expected_iter->account_id, actual_iter->account_id);
    EXPECT_EQ(expected_iter->email, actual_iter->email);
    EXPECT_EQ(expected_iter->access_token, actual_iter->access_token);
  }
}

// This version of FakeGCMDriver is customized around handling accounts and
// connection events for testing GCMAccountTracker.
class CustomFakeGCMDriver : public FakeGCMDriver {
 public:
  CustomFakeGCMDriver();

  CustomFakeGCMDriver(const CustomFakeGCMDriver&) = delete;
  CustomFakeGCMDriver& operator=(const CustomFakeGCMDriver&) = delete;

  ~CustomFakeGCMDriver() override;

  // GCMDriver overrides:
  void SetAccountTokens(
      const std::vector<GCMClient::AccountTokenInfo>& account_tokens) override;
  void AddConnectionObserver(GCMConnectionObserver* observer) override;
  void RemoveConnectionObserver(GCMConnectionObserver* observer) override;
  bool IsConnected() const override { return connected_; }
  base::Time GetLastTokenFetchTime() override;
  void SetLastTokenFetchTime(const base::Time& time) override;

  // Test results and helpers.
  void SetConnected(bool connected);
  void ResetResults();
  bool update_accounts_called() const { return update_accounts_called_; }
  const std::vector<GCMClient::AccountTokenInfo>& accounts() const {
    return accounts_;
  }
  const GCMConnectionObserver* last_connection_observer() const {
    return last_connection_observer_;
  }
  const GCMConnectionObserver* last_removed_connection_observer() const {
    return removed_connection_observer_;
  }

 private:
  bool connected_;
  std::vector<GCMClient::AccountTokenInfo> accounts_;
  bool update_accounts_called_;
  raw_ptr<GCMConnectionObserver, DanglingUntriaged> last_connection_observer_;
  raw_ptr<GCMConnectionObserver, DanglingUntriaged>
      removed_connection_observer_;
  net::IPEndPoint ip_endpoint_;
  base::Time last_token_fetch_time_;
};

CustomFakeGCMDriver::CustomFakeGCMDriver()
    : connected_(true),
      update_accounts_called_(false),
      last_connection_observer_(nullptr),
      removed_connection_observer_(nullptr) {}

CustomFakeGCMDriver::~CustomFakeGCMDriver() {
}

void CustomFakeGCMDriver::SetAccountTokens(
    const std::vector<GCMClient::AccountTokenInfo>& accounts) {
  update_accounts_called_ = true;
  accounts_ = accounts;
}

void CustomFakeGCMDriver::AddConnectionObserver(
    GCMConnectionObserver* observer) {
  last_connection_observer_ = observer;
}

void CustomFakeGCMDriver::RemoveConnectionObserver(
    GCMConnectionObserver* observer) {
  removed_connection_observer_ = observer;
}

void CustomFakeGCMDriver::SetConnected(bool connected) {
  connected_ = connected;
  if (connected && last_connection_observer_)
    last_connection_observer_->OnConnected(ip_endpoint_);
}

void CustomFakeGCMDriver::ResetResults() {
  accounts_.clear();
  update_accounts_called_ = false;
  last_connection_observer_ = nullptr;
  removed_connection_observer_ = nullptr;
}


base::Time CustomFakeGCMDriver::GetLastTokenFetchTime() {
  return last_token_fetch_time_;
}

void CustomFakeGCMDriver::SetLastTokenFetchTime(const base::Time& time) {
  last_token_fetch_time_ = time;
}

}  // namespace

class GCMAccountTrackerTest : public testing::Test {
 public:
  GCMAccountTrackerTest();
  ~GCMAccountTrackerTest() override;

  // Helpers to pass fake info to the tracker.
  CoreAccountInfo AddAccount(const std::string& email);
  CoreAccountInfo SetPrimaryAccount(const std::string& email);
  void ClearPrimaryAccount();
  void RemoveAccount(const CoreAccountId& account_id);

  // Helpers for dealing with OAuth2 access token requests.
  void IssueAccessToken(const CoreAccountId& account_id);
  void IssueExpiredAccessToken(const CoreAccountId& account_id);
  void IssueError(const CoreAccountId& account_id);

  // Accessors to account tracker and gcm driver.
  GCMAccountTracker* tracker() { return tracker_.get(); }
  CustomFakeGCMDriver* driver() { return &driver_; }

  // Accessors to private methods of account tracker.
  bool IsFetchingRequired() const;
  bool IsTokenReportingRequired() const;
  base::TimeDelta GetTimeToNextTokenReporting() const;

  network::TestURLLoaderFactory* test_url_loader_factory() {
    return &test_url_loader_factory_;
  }

 private:
  CustomFakeGCMDriver driver_;

  base::test::SingleThreadTaskEnvironment task_environment_;
  network::TestURLLoaderFactory test_url_loader_factory_;
  signin::IdentityTestEnvironment identity_test_env_;

  std::unique_ptr<GCMAccountTracker> tracker_;
};

GCMAccountTrackerTest::GCMAccountTrackerTest() {
  std::unique_ptr<AccountTracker> gaia_account_tracker(
      new AccountTracker(identity_test_env_.identity_manager()));

  tracker_ = std::make_unique<GCMAccountTracker>(
      std::move(gaia_account_tracker), identity_test_env_.identity_manager(),
      &driver_);
}

GCMAccountTrackerTest::~GCMAccountTrackerTest() {
  if (tracker_)
    tracker_->Shutdown();
}

CoreAccountInfo GCMAccountTrackerTest::AddAccount(const std::string& email) {
  return identity_test_env_.MakeAccountAvailable(email);
}

CoreAccountInfo GCMAccountTrackerTest::SetPrimaryAccount(
    const std::string& email) {
  // NOTE: Setting of the primary account info must be done first on ChromeOS
  // to ensure that AccountTracker and GCMAccountTracker respond as expected
  // when the token is added to the token service.
  // TODO(blundell): On non-ChromeOS, it would be good to add tests wherein
  // setting of the primary account is done afterward to check that the flow
  // that ensues from the GoogleSigninSucceeded callback firing works as
  // expected.
  // TODO(crbug.com/40067875): Delete account-tracking code, latest when
  // ConsentLevel::kSync is cleaned up from the codebase.
  return identity_test_env_.MakePrimaryAccountAvailable(
      email, signin::ConsentLevel::kSync);
}

void GCMAccountTrackerTest::ClearPrimaryAccount() {
  identity_test_env_.ClearPrimaryAccount();
}

void GCMAccountTrackerTest::RemoveAccount(const CoreAccountId& account_id) {
  identity_test_env_.RemoveRefreshTokenForAccount(account_id);
}

void GCMAccountTrackerTest::IssueAccessToken(const CoreAccountId& account_id) {
  identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
      account_id, MakeAccessToken(account_id), base::Time::Max());
}

void GCMAccountTrackerTest::IssueExpiredAccessToken(
    const CoreAccountId& account_id) {
  identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
      account_id, MakeAccessToken(account_id), base::Time::Now());
}

void GCMAccountTrackerTest::IssueError(const CoreAccountId& account_id) {
  identity_test_env_.WaitForAccessTokenRequestIfNecessaryAndRespondWithError(
      account_id,
      GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
}

bool GCMAccountTrackerTest::IsFetchingRequired() const {
  return tracker_->IsTokenFetchingRequired();
}

bool GCMAccountTrackerTest::IsTokenReportingRequired() const {
  return tracker_->IsTokenReportingRequired();
}

base::TimeDelta GCMAccountTrackerTest::GetTimeToNextTokenReporting() const {
  return tracker_->GetTimeToNextTokenReporting();
}

TEST_F(GCMAccountTrackerTest, NoAccounts) {
  EXPECT_FALSE(driver()->update_accounts_called());
  tracker()->Start();
  // Callback should not be called if there where no accounts provided.
  EXPECT_FALSE(driver()->update_accounts_called());
  EXPECT_TRUE(driver()->accounts().empty());
}

// Verifies that callback is called after a token is issued for a single account
// with a specific scope. In this scenario, the underlying account tracker is
// still working when the CompleteCollectingTokens is called for the first time.
TEST_F(GCMAccountTrackerTest, SingleAccount) {
  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);

  tracker()->Start();
  EXPECT_FALSE(driver()->update_accounts_called());

  IssueAccessToken(account1.account_id);
  EXPECT_TRUE(driver()->update_accounts_called());

  std::vector<GCMClient::AccountTokenInfo> expected_accounts;
  expected_accounts.push_back(MakeAccountToken(account1));
  VerifyAccountTokens(expected_accounts, driver()->accounts());
}

TEST_F(GCMAccountTrackerTest, MultipleAccounts) {
  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);
  CoreAccountInfo account2 = AddAccount(kEmail2);

  tracker()->Start();
  EXPECT_FALSE(driver()->update_accounts_called());

  IssueAccessToken(account1.account_id);
  EXPECT_FALSE(driver()->update_accounts_called());

  IssueAccessToken(account2.account_id);
  EXPECT_TRUE(driver()->update_accounts_called());

  std::vector<GCMClient::AccountTokenInfo> expected_accounts;
  expected_accounts.push_back(MakeAccountToken(account1));
  expected_accounts.push_back(MakeAccountToken(account2));
  VerifyAccountTokens(expected_accounts, driver()->accounts());
}

TEST_F(GCMAccountTrackerTest, AccountAdded) {
  tracker()->Start();
  driver()->ResetResults();

  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);
  EXPECT_FALSE(driver()->update_accounts_called());

  IssueAccessToken(account1.account_id);
  EXPECT_TRUE(driver()->update_accounts_called());

  std::vector<GCMClient::AccountTokenInfo> expected_accounts;
  expected_accounts.push_back(MakeAccountToken(account1));
  VerifyAccountTokens(expected_accounts, driver()->accounts());
}

TEST_F(GCMAccountTrackerTest, AccountRemoved) {
  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);
  CoreAccountInfo account2 = AddAccount(kEmail2);

  tracker()->Start();
  IssueAccessToken(account1.account_id);
  IssueAccessToken(account2.account_id);
  EXPECT_TRUE(driver()->update_accounts_called());

  driver()->ResetResults();
  EXPECT_FALSE(driver()->update_accounts_called());

  RemoveAccount(account2.account_id);
  EXPECT_TRUE(driver()->update_accounts_called());

  std::vector<GCMClient::AccountTokenInfo> expected_accounts;
  expected_accounts.push_back(MakeAccountToken(account1));
  VerifyAccountTokens(expected_accounts, driver()->accounts());
}

#if !BUILDFLAG(IS_CHROMEOS)
// Tests that clearing the primary account when having multiple accounts
// does not crash the application.
// Regression test for crbug.com/1234406
TEST_F(GCMAccountTrackerTest, AccountRemovedWithoutSyncConsentNoCrash) {
  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);
  CoreAccountInfo account2 = AddAccount(kEmail2);

  // Set last fetch time to now so that access token fetch is not required
  // but not started.
  driver()->SetLastTokenFetchTime(base::Time::Now());
  tracker()->Start();
  EXPECT_FALSE(driver()->update_accounts_called());

  // Reset the last fetch time to verify that clearing the primary account
  // will not trigger a token fetch.
  driver()->SetLastTokenFetchTime(base::Time());
  EXPECT_EQ(base::TimeDelta(), GetTimeToNextTokenReporting());
  ClearPrimaryAccount();
  EXPECT_TRUE(driver()->update_accounts_called());
}
#endif  // !BUILDFLAG(IS_CHROMEOS)

TEST_F(GCMAccountTrackerTest, GetTokenFailed) {
  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);
  CoreAccountInfo account2 = AddAccount(kEmail2);

  tracker()->Start();
  IssueAccessToken(account1.account_id);
  EXPECT_FALSE(driver()->update_accounts_called());

  IssueError(account2.account_id);

  // Failed token is not retried any more. Account marked as removed.
  EXPECT_EQ(0UL, tracker()->get_pending_token_request_count());
  EXPECT_TRUE(driver()->update_accounts_called());

  std::vector<GCMClient::AccountTokenInfo> expected_accounts;
  expected_accounts.push_back(MakeAccountToken(account1));
  VerifyAccountTokens(expected_accounts, driver()->accounts());
}

TEST_F(GCMAccountTrackerTest, GetTokenFailedAccountRemoved) {
  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);
  CoreAccountInfo account2 = AddAccount(kEmail2);

  tracker()->Start();
  IssueAccessToken(account1.account_id);

  driver()->ResetResults();
  RemoveAccount(account2.account_id);
  IssueError(account2.account_id);

  EXPECT_TRUE(driver()->update_accounts_called());

  std::vector<GCMClient::AccountTokenInfo> expected_accounts;
  expected_accounts.push_back(MakeAccountToken(account1));
  VerifyAccountTokens(expected_accounts, driver()->accounts());
}

TEST_F(GCMAccountTrackerTest, AccountRemovedWhileRequestsPending) {
  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);
  CoreAccountInfo account2 = AddAccount(kEmail2);

  tracker()->Start();
  IssueAccessToken(account1.account_id);
  EXPECT_FALSE(driver()->update_accounts_called());

  RemoveAccount(account2.account_id);
  IssueAccessToken(account2.account_id);
  EXPECT_TRUE(driver()->update_accounts_called());

  std::vector<GCMClient::AccountTokenInfo> expected_accounts;
  expected_accounts.push_back(MakeAccountToken(account1));
  VerifyAccountTokens(expected_accounts, driver()->accounts());
}

// Makes sure that tracker observes GCM connection when running.
TEST_F(GCMAccountTrackerTest, TrackerObservesConnection) {
  EXPECT_EQ(nullptr, driver()->last_connection_observer());
  tracker()->Start();
  EXPECT_EQ(tracker(), driver()->last_connection_observer());
  tracker()->Shutdown();
  EXPECT_EQ(tracker(), driver()->last_removed_connection_observer());
}

// Makes sure that token fetching happens only after connection is established.
TEST_F(GCMAccountTrackerTest, PostponeTokenFetchingUntilConnected) {
  driver()->SetConnected(false);
  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);
  tracker()->Start();

  EXPECT_EQ(0UL, tracker()->get_pending_token_request_count());
  driver()->SetConnected(true);

  EXPECT_EQ(1UL, tracker()->get_pending_token_request_count());
}

TEST_F(GCMAccountTrackerTest, InvalidateExpiredTokens) {
  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);
  CoreAccountInfo account2 = AddAccount(kEmail2);
  tracker()->Start();

  EXPECT_EQ(2UL, tracker()->get_pending_token_request_count());

  IssueExpiredAccessToken(account1.account_id);
  IssueAccessToken(account2.account_id);
  // Because the first token is expired, we expect the sanitize to kick in and
  // clean it up before the SetAccessToken is called. This also means a new
  // token request will be issued
  EXPECT_FALSE(driver()->update_accounts_called());
  EXPECT_EQ(1UL, tracker()->get_pending_token_request_count());
}

// Testing for whether there are still more tokens to be fetched. Typically the
// need for token fetching triggers immediate request, unless there is no
// connection, that is why connection is set on and off in this test.
TEST_F(GCMAccountTrackerTest, IsTokenFetchingRequired) {
  tracker()->Start();
  driver()->SetConnected(false);
  EXPECT_FALSE(IsFetchingRequired());
  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);
  EXPECT_TRUE(IsFetchingRequired());

  driver()->SetConnected(true);
  EXPECT_FALSE(IsFetchingRequired());  // Indicates that fetching has started.
  IssueAccessToken(account1.account_id);
  EXPECT_FALSE(IsFetchingRequired());

  CoreAccountInfo account2 = AddAccount(kEmail2);
  EXPECT_FALSE(IsFetchingRequired());  // Indicates that fetching has started.

  // Disconnect the driver again so that the access token request being
  // fulfilled doesn't immediately cause another access token request (which
  // then would cause IsFetchingRequired() to be false, preventing us from
  // distinguishing this case from the case where IsFetchingRequired() is false
  // because GCMAccountTracker didn't detect that a new access token needs to be
  // fetched).
  driver()->SetConnected(false);
  IssueExpiredAccessToken(account2.account_id);

  // Make sure that if the token was expired it is marked as being needed again.
  EXPECT_TRUE(IsFetchingRequired());
}

// Tests what is the expected time to the next token fetching.
TEST_F(GCMAccountTrackerTest, GetTimeToNextTokenReporting) {
  tracker()->Start();
  // At this point the last token fetch time is never.
  EXPECT_EQ(base::TimeDelta(), GetTimeToNextTokenReporting());

  // Regular case. The tokens have been just reported.
  driver()->SetLastTokenFetchTime(base::Time::Now());
  EXPECT_TRUE(GetTimeToNextTokenReporting() <= base::Seconds(12 * 60 * 60));

  // A case when gcm driver is not yet initialized.
  driver()->SetLastTokenFetchTime(base::Time::Max());
  EXPECT_EQ(base::Seconds(12 * 60 * 60), GetTimeToNextTokenReporting());

  // A case when token reporting calculation is expected to result in more than
  // 12 hours, in which case we expect exactly 12 hours.
  driver()->SetLastTokenFetchTime(base::Time::Now() + base::Days(2));
  EXPECT_EQ(base::Seconds(12 * 60 * 60), GetTimeToNextTokenReporting());
}

// Tests conditions when token reporting is required.
TEST_F(GCMAccountTrackerTest, IsTokenReportingRequired) {
  tracker()->Start();
  // Required because it is overdue.
  EXPECT_TRUE(IsTokenReportingRequired());

  // Not required because it just happened.
  driver()->SetLastTokenFetchTime(base::Time::Now());
  EXPECT_FALSE(IsTokenReportingRequired());

  CoreAccountInfo account1 = SetPrimaryAccount(kEmail1);
  IssueAccessToken(account1.account_id);
  driver()->ResetResults();
  // Reporting was triggered, which means testing for required will give false,
  // but we have the update call.
  RemoveAccount(account1.account_id);
  EXPECT_TRUE(driver()->update_accounts_called());
  EXPECT_FALSE(IsTokenReportingRequired());
}

// TODO(fgorski): Add test for adding account after removal >> make sure it does
// not mark removal.

}  // namespace gcm
