// 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/account_tracker.h"

#include <algorithm>
#include <vector>

#include "base/strings/stringprintf.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

const char kPrimaryAccountEmail[] = "primary_account@example.com";

enum TrackingEventType { SIGN_IN, SIGN_OUT };

class TrackingEvent {
 public:
  TrackingEvent(TrackingEventType type,
                const CoreAccountId& account_id,
                const std::string& gaia_id)
      : type_(type), account_id_(account_id), gaia_id_(gaia_id) {}

  TrackingEvent(TrackingEventType type, const CoreAccountInfo& account_info)
      : type_(type),
        account_id_(account_info.account_id),
        gaia_id_(account_info.gaia) {}

  bool operator==(const TrackingEvent& event) const {
    return type_ == event.type_ && account_id_ == event.account_id_ &&
           gaia_id_ == event.gaia_id_;
  }

  std::string ToString() const {
    const char* typestr = "INVALID";
    switch (type_) {
      case SIGN_IN:
        typestr = " IN";
        break;
      case SIGN_OUT:
        typestr = "OUT";
        break;
    }
    return base::StringPrintf("{ type: %s, account_id: %s, gaia: %s }", typestr,
                              account_id_.ToString().c_str(), gaia_id_.c_str());
  }

 private:
  friend bool CompareByUser(TrackingEvent a, TrackingEvent b);

  TrackingEventType type_;
  CoreAccountId account_id_;
  std::string gaia_id_;
};

bool CompareByUser(TrackingEvent a, TrackingEvent b) {
  return a.account_id_ < b.account_id_;
}

std::string Str(const std::vector<TrackingEvent>& events) {
  std::string str = "[";
  bool needs_comma = false;
  for (auto it = events.begin(); it != events.end(); ++it) {
    if (needs_comma)
      str += ",\n ";
    needs_comma = true;
    str += it->ToString();
  }
  str += "]";
  return str;
}

}  // namespace

namespace gcm {

class AccountTrackerObserver : public AccountTracker::Observer {
 public:
  AccountTrackerObserver() {}
  virtual ~AccountTrackerObserver() {}

  testing::AssertionResult CheckEvents();
  testing::AssertionResult CheckEvents(const TrackingEvent& e1);
  testing::AssertionResult CheckEvents(const TrackingEvent& e1,
                                       const TrackingEvent& e2);
  testing::AssertionResult CheckEvents(const TrackingEvent& e1,
                                       const TrackingEvent& e2,
                                       const TrackingEvent& e3);
  testing::AssertionResult CheckEvents(const TrackingEvent& e1,
                                       const TrackingEvent& e2,
                                       const TrackingEvent& e3,
                                       const TrackingEvent& e4);
  testing::AssertionResult CheckEvents(const TrackingEvent& e1,
                                       const TrackingEvent& e2,
                                       const TrackingEvent& e3,
                                       const TrackingEvent& e4,
                                       const TrackingEvent& e5);
  testing::AssertionResult CheckEvents(const TrackingEvent& e1,
                                       const TrackingEvent& e2,
                                       const TrackingEvent& e3,
                                       const TrackingEvent& e4,
                                       const TrackingEvent& e5,
                                       const TrackingEvent& e6);
  void Clear();
  void SortEventsByUser();

  // AccountTracker::Observer implementation
  void OnAccountSignInChanged(const CoreAccountInfo& account,
                              bool is_signed_in) override;

 private:
  testing::AssertionResult CheckEvents(
      const std::vector<TrackingEvent>& events);

  std::vector<TrackingEvent> events_;
};

void AccountTrackerObserver::OnAccountSignInChanged(
    const CoreAccountInfo& account,
    bool is_signed_in) {
  events_.push_back(TrackingEvent(is_signed_in ? SIGN_IN : SIGN_OUT,
                                  account.account_id, account.gaia));
}

void AccountTrackerObserver::Clear() {
  events_.clear();
}

void AccountTrackerObserver::SortEventsByUser() {
  std::stable_sort(events_.begin(), events_.end(), CompareByUser);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents() {
  std::vector<TrackingEvent> events;
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1,
    const TrackingEvent& e2) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  events.push_back(e2);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1,
    const TrackingEvent& e2,
    const TrackingEvent& e3) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  events.push_back(e2);
  events.push_back(e3);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1,
    const TrackingEvent& e2,
    const TrackingEvent& e3,
    const TrackingEvent& e4) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  events.push_back(e2);
  events.push_back(e3);
  events.push_back(e4);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1,
    const TrackingEvent& e2,
    const TrackingEvent& e3,
    const TrackingEvent& e4,
    const TrackingEvent& e5) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  events.push_back(e2);
  events.push_back(e3);
  events.push_back(e4);
  events.push_back(e5);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const TrackingEvent& e1,
    const TrackingEvent& e2,
    const TrackingEvent& e3,
    const TrackingEvent& e4,
    const TrackingEvent& e5,
    const TrackingEvent& e6) {
  std::vector<TrackingEvent> events;
  events.push_back(e1);
  events.push_back(e2);
  events.push_back(e3);
  events.push_back(e4);
  events.push_back(e5);
  events.push_back(e6);
  return CheckEvents(events);
}

testing::AssertionResult AccountTrackerObserver::CheckEvents(
    const std::vector<TrackingEvent>& events) {
  std::string maybe_newline = (events.size() + events_.size()) > 2 ? "\n" : "";
  testing::AssertionResult result(
      (events_ == events)
          ? testing::AssertionSuccess()
          : (testing::AssertionFailure()
             << "Expected " << maybe_newline << Str(events) << ", "
             << maybe_newline << "Got " << maybe_newline << Str(events_)));
  events_.clear();
  return result;
}

class AccountTrackerTest : public testing::Test {
 public:
  AccountTrackerTest() {}

  ~AccountTrackerTest() override {}

  void SetUp() override {
    account_tracker_.reset(
        new AccountTracker(identity_test_env_.identity_manager()));
    account_tracker_->AddObserver(&observer_);
  }

  void TearDown() override {
    account_tracker_->RemoveObserver(&observer_);
    account_tracker_->Shutdown();
  }

  AccountTrackerObserver* observer() { return &observer_; }

  AccountTracker* account_tracker() { return account_tracker_.get(); }

  // Helpers to pass fake events to the tracker.

  // Sets the primary account info. Returns the account ID of the
  // newly-set account.
  // NOTE: On ChromeOS, the login callback is never fired in production (since
  // the underlying GoogleSigninSucceeded callback is never sent). Tests that
  // exercise functionality dependent on that callback firing are not relevant
  // on ChromeOS and should simply not run on that platform.
  CoreAccountInfo SetActiveAccount(const std::string& email) {
    return identity_test_env_.SetPrimaryAccount(email);
  }

// Helpers that go through a logout flow.
// NOTE: On ChromeOS, the logout callback is never fired in production (since
// the underlying GoogleSignedOut callback is never sent). Tests that exercise
// functionality dependent on that callback firing are not relevant on ChromeOS
// and should simply not run on that platform.
#if !defined(OS_CHROMEOS)
  void NotifyLogoutOfPrimaryAccountOnly() {
    identity_test_env_.ClearPrimaryAccount(
        signin::ClearPrimaryAccountPolicy::KEEP_ALL_ACCOUNTS);
  }

  void NotifyLogoutOfAllAccounts() {
    identity_test_env_.ClearPrimaryAccount(
        signin::ClearPrimaryAccountPolicy::REMOVE_ALL_ACCOUNTS);
  }
#endif

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

  void NotifyTokenAvailable(const CoreAccountId& account_id) {
    identity_test_env_.SetRefreshTokenForAccount(account_id);
  }

  void NotifyTokenRevoked(const CoreAccountId& account_id) {
    identity_test_env_.RemoveRefreshTokenForAccount(account_id);
  }

  CoreAccountInfo SetupPrimaryLogin() {
    // Initial setup for tests that start with a signed in profile.
    CoreAccountInfo primary_account = SetActiveAccount(kPrimaryAccountEmail);
    NotifyTokenAvailable(primary_account.account_id);
    observer()->Clear();

    return primary_account;
  }

 private:
  // net:: stuff needs IO message loop.
  base::test::SingleThreadTaskEnvironment task_environment_{
      base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
  signin::IdentityTestEnvironment identity_test_env_;

  std::unique_ptr<AccountTracker> account_tracker_;
  AccountTrackerObserver observer_;
};

// Primary tests just involve the Active account

TEST_F(AccountTrackerTest, PrimaryNoEventsBeforeLogin) {
  CoreAccountInfo account = AddAccountWithToken("me@dummy.com");
  NotifyTokenRevoked(account.account_id);

// Logout is not possible on ChromeOS.
#if !defined(OS_CHROMEOS)
  NotifyLogoutOfAllAccounts();
#endif

  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, PrimaryLoginThenTokenAvailable) {
  CoreAccountInfo primary_account = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account.account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, primary_account)));
}

TEST_F(AccountTrackerTest, PrimaryRevoke) {
  CoreAccountInfo primary_account = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account.account_id);
  observer()->Clear();

  NotifyTokenRevoked(primary_account.account_id);
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_OUT, primary_account)));
}

TEST_F(AccountTrackerTest, PrimaryRevokeThenTokenAvailable) {
  CoreAccountInfo primary_account = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account.account_id);
  NotifyTokenRevoked(primary_account.account_id);
  observer()->Clear();

  NotifyTokenAvailable(primary_account.account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, primary_account)));
}

// These tests exercise true login/logout, which are not possible on ChromeOS.
#if !defined(OS_CHROMEOS)
TEST_F(AccountTrackerTest, PrimaryTokenAvailableThenLogin) {
  AddAccountWithToken(kPrimaryAccountEmail);
  EXPECT_TRUE(observer()->CheckEvents());

  CoreAccountInfo primary_account = SetActiveAccount(kPrimaryAccountEmail);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, primary_account)));
}

TEST_F(AccountTrackerTest, PrimaryTokenAvailableAndRevokedThenLogin) {
  CoreAccountInfo primary_account = AddAccountWithToken(kPrimaryAccountEmail);
  EXPECT_TRUE(observer()->CheckEvents());

  NotifyTokenRevoked(primary_account.account_id);
  EXPECT_TRUE(observer()->CheckEvents());

  SetActiveAccount(kPrimaryAccountEmail);
  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, PrimaryRevokeThenLogin) {
  CoreAccountInfo primary_account = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account.account_id);
  NotifyLogoutOfAllAccounts();
  observer()->Clear();

  SetActiveAccount(kPrimaryAccountEmail);
  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, PrimaryLogoutThenRevoke) {
  CoreAccountInfo primary_account = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account.account_id);
  observer()->Clear();

  NotifyLogoutOfAllAccounts();
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_OUT, primary_account)));

  NotifyTokenRevoked(primary_account.account_id);
  EXPECT_TRUE(observer()->CheckEvents());
}

#endif

// Non-primary accounts

TEST_F(AccountTrackerTest, Available) {
  SetupPrimaryLogin();

  CoreAccountInfo account = AddAccountWithToken("user@example.com");
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account)));
}

TEST_F(AccountTrackerTest, AvailableRevokeAvailable) {
  SetupPrimaryLogin();

  CoreAccountInfo account = AddAccountWithToken("user@example.com");
  NotifyTokenRevoked(account.account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account),
                                      TrackingEvent(SIGN_OUT, account)));

  NotifyTokenAvailable(account.account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account)));
}

TEST_F(AccountTrackerTest, AvailableRevokeRevoke) {
  SetupPrimaryLogin();

  CoreAccountInfo account = AddAccountWithToken("user@example.com");
  NotifyTokenRevoked(account.account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account),
                                      TrackingEvent(SIGN_OUT, account)));

  NotifyTokenRevoked(account.account_id);
  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, AvailableAvailable) {
  SetupPrimaryLogin();

  CoreAccountInfo account = AddAccountWithToken("user@example.com");
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, account)));

  NotifyTokenAvailable(account.account_id);
  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, TwoAccounts) {
  SetupPrimaryLogin();

  CoreAccountInfo alpha_account = AddAccountWithToken("alpha@example.com");
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, alpha_account)));

  CoreAccountInfo beta_account = AddAccountWithToken("beta@example.com");
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_IN, beta_account)));

  NotifyTokenRevoked(alpha_account.account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_OUT, alpha_account)));

  NotifyTokenRevoked(beta_account.account_id);
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_OUT, beta_account)));
}

// Primary/non-primary interactions

TEST_F(AccountTrackerTest, MultiNoEventsBeforeLogin) {
  CoreAccountInfo account1 = AddAccountWithToken("user@example.com");
  CoreAccountInfo account2 = AddAccountWithToken("user2@example.com");
  NotifyTokenRevoked(account2.account_id);
  NotifyTokenRevoked(account2.account_id);

// Logout is not possible on ChromeOS.
#if !defined(OS_CHROMEOS)
  NotifyLogoutOfAllAccounts();
#endif

  EXPECT_TRUE(observer()->CheckEvents());
}

TEST_F(AccountTrackerTest, MultiRevokePrimaryDoesNotRemoveAllAccounts) {
  CoreAccountInfo primary_account = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account.account_id);
  CoreAccountInfo account = AddAccountWithToken("user@example.com");
  observer()->Clear();

  NotifyTokenRevoked(primary_account.account_id);
  observer()->SortEventsByUser();
  EXPECT_TRUE(
      observer()->CheckEvents(TrackingEvent(SIGN_OUT, primary_account)));
}

TEST_F(AccountTrackerTest, GetAccountsPrimary) {
  CoreAccountInfo primary_account = SetupPrimaryLogin();

  std::vector<CoreAccountInfo> account = account_tracker()->GetAccounts();
  EXPECT_EQ(1ul, account.size());
  EXPECT_EQ(primary_account.account_id, account[0].account_id);
  EXPECT_EQ(primary_account.gaia, account[0].gaia);
  EXPECT_EQ(primary_account.email, account[0].email);
}

TEST_F(AccountTrackerTest, GetAccountsSignedOut) {
  std::vector<CoreAccountInfo> accounts = account_tracker()->GetAccounts();
  EXPECT_EQ(0ul, accounts.size());
}

TEST_F(AccountTrackerTest, GetMultipleAccounts) {
  CoreAccountInfo primary_account = SetupPrimaryLogin();
  CoreAccountInfo alpha_account = AddAccountWithToken("alpha@example.com");
  CoreAccountInfo beta_account = AddAccountWithToken("beta@example.com");

  std::vector<CoreAccountInfo> account = account_tracker()->GetAccounts();
  EXPECT_EQ(3ul, account.size());
  EXPECT_EQ(primary_account.account_id, account[0].account_id);
  EXPECT_EQ(primary_account.email, account[0].email);
  EXPECT_EQ(primary_account.gaia, account[0].gaia);

  EXPECT_EQ(alpha_account.account_id, account[1].account_id);
  EXPECT_EQ(alpha_account.email, account[1].email);
  EXPECT_EQ(alpha_account.gaia, account[1].gaia);

  EXPECT_EQ(beta_account.account_id, account[2].account_id);
  EXPECT_EQ(beta_account.email, account[2].email);
  EXPECT_EQ(beta_account.gaia, account[2].gaia);
}

TEST_F(AccountTrackerTest, GetAccountsReturnNothingWhenPrimarySignedOut) {
  CoreAccountInfo primary_account = SetupPrimaryLogin();

  CoreAccountInfo zeta_account = AddAccountWithToken("zeta@example.com");
  CoreAccountInfo alpha_account = AddAccountWithToken("alpha@example.com");

  NotifyTokenRevoked(primary_account.account_id);

  std::vector<CoreAccountInfo> account = account_tracker()->GetAccounts();
  EXPECT_EQ(0ul, account.size());
}

// This test exercises true login/logout, which are not possible on ChromeOS.
#if !defined(OS_CHROMEOS)
TEST_F(AccountTrackerTest, MultiLogoutRemovesAllAccounts) {
  CoreAccountInfo primary_account = SetActiveAccount(kPrimaryAccountEmail);
  NotifyTokenAvailable(primary_account.account_id);
  CoreAccountInfo account = AddAccountWithToken("user@example.com");
  observer()->Clear();

  NotifyLogoutOfAllAccounts();
  observer()->SortEventsByUser();
  EXPECT_TRUE(observer()->CheckEvents(TrackingEvent(SIGN_OUT, primary_account),
                                      TrackingEvent(SIGN_OUT, account)));
}
#endif

}  // namespace gcm
