// 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 "components/gcm_driver/gcm_account_tracker.h"

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

#include "base/macros.h"
#include "base/test/scoped_task_environment.h"
#include "components/gcm_driver/fake_gcm_driver.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/identity/public/cpp/identity_test_environment.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 kOAuthURL[] = "https://www.googleapis.com/oauth2/v1/userinfo";

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

std::string AccountIdToObfuscatedId(const std::string& account_id) {
  return "obfid-" + account_id;
}

std::string GetValidTokenInfoResponse(const std::string& account_id) {
  return std::string("{ \"id\": \"") + AccountIdToObfuscatedId(account_id) +
         "\" }";
}

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

GCMClient::AccountTokenInfo MakeAccountToken(const std::string& account_id) {
  GCMClient::AccountTokenInfo token_info;
  token_info.account_id = account_id;

  // TODO(https://crbug.com/856170): 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_id;
  token_info.access_token = MakeAccessToken(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() 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_;
  GCMConnectionObserver* last_connection_observer_;
  GCMConnectionObserver* removed_connection_observer_;
  net::IPEndPoint ip_endpoint_;
  base::Time last_token_fetch_time_;

  DISALLOW_COPY_AND_ASSIGN(CustomFakeGCMDriver);
};

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. Tests should have either a pair
  // of Start(Primary)/FinishAccountAddition or Add(Primary)Account per
  // account. Don't mix. Any methods that return an std::string are returning
  // the account ID of the newly-added account, which can then be passed into
  // any methods that take in an account ID.
  // Call to RemoveAccount is not mandatory.
  std::string StartAccountAddition(const std::string& email);
  std::string StartPrimaryAccountAddition(const std::string& email);
  void FinishAccountAddition(const std::string& account_id);
  std::string AddAccount(const std::string& email);
  std::string AddPrimaryAccount(const std::string& email);
  void RemoveAccount(const std::string& account_id);

  // Helpers for dealing with OAuth2 access token requests.
  void IssueAccessToken(const std::string& account_id);
  void IssueExpiredAccessToken(const std::string& account_id);
  void IssueError(const std::string& 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::ScopedTaskEnvironment task_environment_;
  network::TestURLLoaderFactory test_url_loader_factory_;
  identity::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(),
      base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
          &test_url_loader_factory_)));

  tracker_.reset(new GCMAccountTracker(std::move(gaia_account_tracker),
                                       identity_test_env_.identity_manager(),
                                       &driver_));
}

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

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

std::string GCMAccountTrackerTest::StartPrimaryAccountAddition(
    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.
return identity_test_env_.MakePrimaryAccountAvailable(email).account_id;
}

void GCMAccountTrackerTest::FinishAccountAddition(
    const std::string& account_id) {
  IssueAccessToken(account_id);

  EXPECT_TRUE(test_url_loader_factory()->IsPending(kOAuthURL));
  test_url_loader_factory()->SimulateResponseForPendingRequest(
      GURL(kOAuthURL), network::URLLoaderCompletionStatus(net::OK),
      network::CreateResourceResponseHead(net::HTTP_OK),
      GetValidTokenInfoResponse(account_id));

  GetValidTokenInfoResponse(account_id);
}

std::string GCMAccountTrackerTest::AddPrimaryAccount(const std::string& email) {
  std::string account_id = StartPrimaryAccountAddition(email);
  FinishAccountAddition(account_id);
  return account_id;
}

std::string GCMAccountTrackerTest::AddAccount(const std::string& email) {
  std::string account_id = StartAccountAddition(email);
  FinishAccountAddition(account_id);
  return account_id;
}

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

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

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

void GCMAccountTrackerTest::IssueError(const std::string& 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) {
  std::string account_id1 = StartPrimaryAccountAddition(kEmail1);

  tracker()->Start();
  // We don't have any accounts to report, but given the inner account tracker
  // is still working we don't make a call with empty accounts list.
  EXPECT_FALSE(driver()->update_accounts_called());

  // This concludes the work of inner account tracker.
  FinishAccountAddition(account_id1);
  IssueAccessToken(account_id1);

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

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

TEST_F(GCMAccountTrackerTest, MultipleAccounts) {
  std::string account_id1 = StartPrimaryAccountAddition(kEmail1);

  std::string account_id2 = StartAccountAddition(kEmail2);

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

  FinishAccountAddition(account_id1);
  IssueAccessToken(account_id1);
  EXPECT_FALSE(driver()->update_accounts_called());

  FinishAccountAddition(account_id2);
  IssueAccessToken(account_id2);
  EXPECT_TRUE(driver()->update_accounts_called());

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

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

  std::string account_id1 = AddPrimaryAccount(kEmail1);
  EXPECT_FALSE(driver()->update_accounts_called());

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

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

TEST_F(GCMAccountTrackerTest, AccountRemoved) {
  std::string account_id1 = AddPrimaryAccount(kEmail1);
  std::string account_id2 = AddAccount(kEmail2);

  tracker()->Start();
  IssueAccessToken(account_id1);
  IssueAccessToken(account_id2);
  EXPECT_TRUE(driver()->update_accounts_called());

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

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

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

TEST_F(GCMAccountTrackerTest, GetTokenFailed) {
  std::string account_id1 = AddPrimaryAccount(kEmail1);
  std::string account_id2 = AddAccount(kEmail2);

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

  IssueError(account_id2);

  // 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(account_id1));
  VerifyAccountTokens(expected_accounts, driver()->accounts());
}

TEST_F(GCMAccountTrackerTest, GetTokenFailedAccountRemoved) {
  std::string account_id1 = AddPrimaryAccount(kEmail1);
  std::string account_id2 = AddAccount(kEmail2);

  tracker()->Start();
  IssueAccessToken(account_id1);

  driver()->ResetResults();
  RemoveAccount(account_id2);
  IssueError(account_id2);

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

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

TEST_F(GCMAccountTrackerTest, AccountRemovedWhileRequestsPending) {
  std::string account_id1 = AddPrimaryAccount(kEmail1);
  std::string account_id2 = AddAccount(kEmail2);

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

  RemoveAccount(account_id2);
  IssueAccessToken(account_id2);
  EXPECT_TRUE(driver()->update_accounts_called());

  std::vector<GCMClient::AccountTokenInfo> expected_accounts;
  expected_accounts.push_back(MakeAccountToken(account_id1));
  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);
  std::string account_id1 = StartPrimaryAccountAddition(kEmail1);
  tracker()->Start();
  FinishAccountAddition(account_id1);

  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) {
  std::string account_id1 = StartPrimaryAccountAddition(kEmail1);
  std::string account_id2 = StartAccountAddition(kEmail2);
  tracker()->Start();
  FinishAccountAddition(account_id1);
  FinishAccountAddition(account_id2);

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

  IssueExpiredAccessToken(account_id1);
  IssueAccessToken(account_id2);
  // 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());
  std::string account_id1 = StartPrimaryAccountAddition(kEmail1);
  FinishAccountAddition(account_id1);
  EXPECT_TRUE(IsFetchingRequired());

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

  std::string account_id2 = StartAccountAddition(kEmail2);
  FinishAccountAddition(account_id2);
  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(account_id2);

  // 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::TimeDelta::FromSeconds(12 * 60 * 60));

  // A case when gcm driver is not yet initialized.
  driver()->SetLastTokenFetchTime(base::Time::Max());
  EXPECT_EQ(base::TimeDelta::FromSeconds(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::TimeDelta::FromDays(2));
  EXPECT_EQ(base::TimeDelta::FromSeconds(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());

  std::string account_id1 = AddPrimaryAccount(kEmail1);
  IssueAccessToken(account_id1);
  driver()->ResetResults();
  // Reporting was triggered, which means testing for required will give false,
  // but we have the update call.
  RemoveAccount(account_id1);
  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
