// Copyright 2016 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/signin/core/browser/account_investigator.h"

#include <map>
#include <string>
#include <vector>

#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_task_environment.h"
#include "base/timer/timer.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/signin/core/browser/signin_metrics.h"
#include "components/signin/core/browser/signin_pref_names.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "services/identity/public/cpp/identity_test_environment.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::HistogramTester;
using base::Time;
using base::TimeDelta;
using gaia::ListedAccount;
using signin_metrics::AccountRelation;
using signin_metrics::ReportingType;

class AccountInvestigatorTest : public testing::Test {
 protected:
  AccountInvestigatorTest()
      : identity_test_env_(&test_url_loader_factory_, &prefs_),
        investigator_(&prefs_, identity_test_env_.identity_manager()) {
    AccountInvestigator::RegisterPrefs(prefs_.registry());
  }

  ~AccountInvestigatorTest() override { investigator_.Shutdown(); }

  identity::IdentityTestEnvironment* identity_test_env() {
    return &identity_test_env_;
  }
  PrefService* pref_service() { return &prefs_; }
  AccountInvestigator* investigator() { return &investigator_; }

  // Wrappers to invoke private methods through friend class.
  TimeDelta Delay(const Time previous,
                  const Time now,
                  const TimeDelta interval) {
    return AccountInvestigator::CalculatePeriodicDelay(previous, now, interval);
  }
  std::string Hash(const std::vector<ListedAccount>& signed_in_accounts,
                   const std::vector<ListedAccount>& signed_out_accounts) {
    return AccountInvestigator::HashAccounts(signed_in_accounts,
                                             signed_out_accounts);
  }
  AccountRelation Relation(
      const AccountInfo& account_info,
      const std::vector<ListedAccount>& signed_in_accounts,
      const std::vector<ListedAccount>& signed_out_accounts) {
    return AccountInvestigator::DiscernRelation(
        account_info, signed_in_accounts, signed_out_accounts);
  }
  void SharedReport(const std::vector<ListedAccount>& signed_in_accounts,
                    const std::vector<ListedAccount>& signed_out_accounts,
                    const Time now,
                    const ReportingType type) {
    investigator_.SharedCookieJarReport(signed_in_accounts, signed_out_accounts,
                                        now, type);
  }
  void TryPeriodicReport() { investigator_.TryPeriodicReport(); }
  bool* periodic_pending() { return &investigator_.periodic_pending_; }
  bool* previously_authenticated() {
    return &investigator_.previously_authenticated_;
  }
  base::OneShotTimer* timer() { return &investigator_.timer_; }

  void ExpectRelationReport(
      const std::vector<ListedAccount> signed_in_accounts,
      const std::vector<ListedAccount> signed_out_accounts,
      const ReportingType type,
      const AccountRelation expected) {
    HistogramTester histogram_tester;
    investigator_.SignedInAccountRelationReport(signed_in_accounts,
                                                signed_out_accounts, type);
    ExpectRelationReport(type, histogram_tester, expected);
  }

  void ExpectRelationReport(const ReportingType type,
                            const HistogramTester& histogram_tester,
                            const AccountRelation expected) {
    histogram_tester.ExpectUniqueSample(
        "Signin.CookieJar.ChromeAccountRelation" + suffix_[type],
        static_cast<int>(expected), 1);
  }

  // If |relation| is a nullptr, then it should not have been recorded.
  // If |stable_age| is a nullptr, then we're not sure what the expected time
  // should have been, but it still should have been recorded.
  void ExpectSharedReportHistograms(const ReportingType type,
                                    const HistogramTester& histogram_tester,
                                    const TimeDelta* stable_age,
                                    const int signed_in_count,
                                    const int signed_out_count,
                                    const int total_count,
                                    const AccountRelation* relation,
                                    const bool is_shared) {
    if (stable_age) {
      histogram_tester.ExpectUniqueSample(
          "Signin.CookieJar.StableAge" + suffix_[type], stable_age->InSeconds(),
          1);
    } else {
      histogram_tester.ExpectTotalCount(
          "Signin.CookieJar.StableAge" + suffix_[type], 1);
    }
    histogram_tester.ExpectUniqueSample(
        "Signin.CookieJar.SignedInCount" + suffix_[type], signed_in_count, 1);
    histogram_tester.ExpectUniqueSample(
        "Signin.CookieJar.SignedOutCount" + suffix_[type], signed_out_count, 1);
    histogram_tester.ExpectUniqueSample(
        "Signin.CookieJar.TotalCount" + suffix_[type], total_count, 1);
    if (relation) {
      histogram_tester.ExpectUniqueSample(
          "Signin.CookieJar.ChromeAccountRelation" + suffix_[type],
          static_cast<int>(*relation), 1);
    } else {
      histogram_tester.ExpectTotalCount(
          "Signin.CookieJar.ChromeAccountRelation" + suffix_[type], 0);
    }
    histogram_tester.ExpectUniqueSample("Signin.IsShared" + suffix_[type],
                                        is_shared, 1);
  }

 private:
  // Timer needs a message loop.
  base::test::ScopedTaskEnvironment task_environment_;
  sync_preferences::TestingPrefServiceSyncable prefs_;
  network::TestURLLoaderFactory test_url_loader_factory_;
  identity::IdentityTestEnvironment identity_test_env_;
  AccountInvestigator investigator_;
  std::map<ReportingType, std::string> suffix_ = {
      {ReportingType::PERIODIC, "_Periodic"},
      {ReportingType::ON_CHANGE, "_OnChange"}};
};

namespace {

ListedAccount Account(const std::string& id) {
  ListedAccount account;
  account.id = id;
  return account;
}

AccountInfo ToAccountInfo(ListedAccount account) {
  AccountInfo account_info;
  account_info.account_id = account.id;
  account_info.gaia = account.gaia_id;
  account_info.email = account.email;
  return account_info;
}

// NOTE: IdentityTestEnvironment uses a prefix for generating gaia IDs:
// "gaia_id_for_". For this reason, the tests prefix expected account IDs
// used so that there is a match.
const std::string kGaiaId1 = identity::GetTestGaiaIdForEmail("1@mail.com");
const std::string kGaiaId2 = identity::GetTestGaiaIdForEmail("2@mail.com");
const std::string kGaiaId3 = identity::GetTestGaiaIdForEmail("3@mail.com");

const ListedAccount one(Account(kGaiaId1));
const ListedAccount two(Account(kGaiaId2));
const ListedAccount three(Account(kGaiaId3));

const std::vector<ListedAccount> no_accounts{};
const std::vector<ListedAccount> just_one{one};
const std::vector<ListedAccount> just_two{two};
const std::vector<ListedAccount> both{one, two};
const std::vector<ListedAccount> both_reversed{two, one};

TEST_F(AccountInvestigatorTest, CalculatePeriodicDelay) {
  const Time epoch;
  const TimeDelta day(TimeDelta::FromDays(1));
  const TimeDelta big(TimeDelta::FromDays(1000));

  EXPECT_EQ(day, Delay(epoch, epoch, day));
  EXPECT_EQ(day, Delay(epoch + big, epoch + big, day));
  EXPECT_EQ(TimeDelta(), Delay(epoch, epoch + big, day));
  EXPECT_EQ(day, Delay(epoch + big, epoch, day));
  EXPECT_EQ(day, Delay(epoch, epoch + day, TimeDelta::FromDays(2)));
}

TEST_F(AccountInvestigatorTest, HashAccounts) {
  EXPECT_EQ(Hash(no_accounts, no_accounts), Hash(no_accounts, no_accounts));
  EXPECT_EQ(Hash(just_one, just_two), Hash(just_one, just_two));
  EXPECT_EQ(Hash(both, no_accounts), Hash(both, no_accounts));
  EXPECT_EQ(Hash(no_accounts, both), Hash(no_accounts, both));
  EXPECT_EQ(Hash(both, no_accounts), Hash(both_reversed, no_accounts));
  EXPECT_EQ(Hash(no_accounts, both), Hash(no_accounts, both_reversed));

  EXPECT_NE(Hash(no_accounts, no_accounts), Hash(just_one, no_accounts));
  EXPECT_NE(Hash(no_accounts, no_accounts), Hash(no_accounts, just_one));
  EXPECT_NE(Hash(just_one, no_accounts), Hash(just_two, no_accounts));
  EXPECT_NE(Hash(just_one, no_accounts), Hash(both, no_accounts));
  EXPECT_NE(Hash(just_one, no_accounts), Hash(no_accounts, just_one));
}

TEST_F(AccountInvestigatorTest, DiscernRelation) {
  EXPECT_EQ(AccountRelation::EMPTY_COOKIE_JAR,
            Relation(ToAccountInfo(one), no_accounts, no_accounts));
  EXPECT_EQ(AccountRelation::SINGLE_SIGNED_IN_MATCH_NO_SIGNED_OUT,
            Relation(ToAccountInfo(one), just_one, no_accounts));
  EXPECT_EQ(AccountRelation::SINGLE_SINGED_IN_MATCH_WITH_SIGNED_OUT,
            Relation(ToAccountInfo(one), just_one, just_two));
  EXPECT_EQ(AccountRelation::WITH_SIGNED_IN_NO_MATCH,
            Relation(ToAccountInfo(one), just_two, no_accounts));
  EXPECT_EQ(AccountRelation::ONE_OF_SIGNED_IN_MATCH_ANY_SIGNED_OUT,
            Relation(ToAccountInfo(one), both, just_one));
  EXPECT_EQ(AccountRelation::ONE_OF_SIGNED_IN_MATCH_ANY_SIGNED_OUT,
            Relation(ToAccountInfo(one), both, no_accounts));
  EXPECT_EQ(AccountRelation::NO_SIGNED_IN_ONE_OF_SIGNED_OUT_MATCH,
            Relation(ToAccountInfo(one), no_accounts, both));
  EXPECT_EQ(AccountRelation::NO_SIGNED_IN_SINGLE_SIGNED_OUT_MATCH,
            Relation(ToAccountInfo(one), no_accounts, just_one));
  EXPECT_EQ(AccountRelation::WITH_SIGNED_IN_ONE_OF_SIGNED_OUT_MATCH,
            Relation(ToAccountInfo(one), just_two, just_one));
  EXPECT_EQ(AccountRelation::NO_SIGNED_IN_WITH_SIGNED_OUT_NO_MATCH,
            Relation(ToAccountInfo(three), no_accounts, both));
}

TEST_F(AccountInvestigatorTest, SignedInAccountRelationReport) {
  ExpectRelationReport(just_one, no_accounts, ReportingType::PERIODIC,
                       AccountRelation::WITH_SIGNED_IN_NO_MATCH);
  identity_test_env()->SetPrimaryAccount("1@mail.com");
  ExpectRelationReport(just_one, no_accounts, ReportingType::PERIODIC,
                       AccountRelation::SINGLE_SIGNED_IN_MATCH_NO_SIGNED_OUT);
  ExpectRelationReport(just_two, no_accounts, ReportingType::ON_CHANGE,
                       AccountRelation::WITH_SIGNED_IN_NO_MATCH);
}

TEST_F(AccountInvestigatorTest, SharedCookieJarReportEmpty) {
  const HistogramTester histogram_tester;
  const TimeDelta expected_stable_age;
  SharedReport(no_accounts, no_accounts, Time(), ReportingType::PERIODIC);
  ExpectSharedReportHistograms(ReportingType::PERIODIC, histogram_tester,
                               &expected_stable_age, 0, 0, 0, nullptr, false);
}

TEST_F(AccountInvestigatorTest, SharedCookieJarReportWithAccount) {
  identity_test_env()->SetPrimaryAccount("1@mail.com");
  base::Time now = base::Time::Now();
  pref_service()->SetDouble(prefs::kGaiaCookieChangedTime, now.ToDoubleT());
  const AccountRelation expected_relation(
      AccountRelation::ONE_OF_SIGNED_IN_MATCH_ANY_SIGNED_OUT);
  const HistogramTester histogram_tester;
  const TimeDelta expected_stable_age(TimeDelta::FromDays(1));
  SharedReport(both, no_accounts, now + TimeDelta::FromDays(1),
               ReportingType::ON_CHANGE);
  ExpectSharedReportHistograms(ReportingType::ON_CHANGE, histogram_tester,
                               &expected_stable_age, 2, 0, 2,
                               &expected_relation, false);
}

TEST_F(AccountInvestigatorTest, OnGaiaAccountsInCookieUpdatedError) {
  const HistogramTester histogram_tester;
  identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info = {
      /*accounts_are_fresh=*/true, just_one, no_accounts};
  GoogleServiceAuthError error(GoogleServiceAuthError::SERVICE_UNAVAILABLE);
  investigator()->OnAccountsInCookieUpdated(accounts_in_cookie_jar_info, error);
  EXPECT_EQ(0u, histogram_tester.GetTotalCountsForPrefix("Signin.").size());
}

TEST_F(AccountInvestigatorTest, OnGaiaAccountsInCookieUpdatedOnChange) {
  const HistogramTester histogram_tester;
  identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info = {
      /*accounts_are_fresh=*/true, just_one, no_accounts};
  investigator()->OnAccountsInCookieUpdated(
      accounts_in_cookie_jar_info, GoogleServiceAuthError::AuthErrorNone());
  ExpectSharedReportHistograms(ReportingType::ON_CHANGE, histogram_tester,
                               nullptr, 1, 0, 1, nullptr, false);
}

TEST_F(AccountInvestigatorTest, OnGaiaAccountsInCookieUpdatedSigninOnly) {
  // Initial update to simulate the update on first-time-run.
  investigator()->OnAccountsInCookieUpdated(
      identity::AccountsInCookieJarInfo(),
      GoogleServiceAuthError::AuthErrorNone());

  const HistogramTester histogram_tester;
  identity_test_env()->SetPrimaryAccount("1@mail.com");
  pref_service()->SetString(prefs::kGaiaCookieHash,
                            Hash(just_one, no_accounts));
  identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info = {
      /*accounts_are_fresh=*/true, just_one, no_accounts};
  investigator()->OnAccountsInCookieUpdated(
      accounts_in_cookie_jar_info, GoogleServiceAuthError::AuthErrorNone());
  EXPECT_EQ(1u, histogram_tester.GetTotalCountsForPrefix("Signin.").size());
  ExpectRelationReport(ReportingType::ON_CHANGE, histogram_tester,
                       AccountRelation::SINGLE_SIGNED_IN_MATCH_NO_SIGNED_OUT);
}

TEST_F(AccountInvestigatorTest,
       OnGaiaAccountsInCookieUpdatedSigninSignOutOfContent) {
  const HistogramTester histogram_tester;
  identity_test_env()->SetPrimaryAccount("1@mail.com");
  identity::AccountsInCookieJarInfo accounts_in_cookie_jar_info = {
      /*accounts_are_fresh=*/true, just_one, no_accounts};
  investigator()->OnAccountsInCookieUpdated(
      accounts_in_cookie_jar_info, GoogleServiceAuthError::AuthErrorNone());
  ExpectRelationReport(ReportingType::ON_CHANGE, histogram_tester,
                       AccountRelation::SINGLE_SIGNED_IN_MATCH_NO_SIGNED_OUT);

  // Simulate a sign out of the content area.
  const HistogramTester histogram_tester2;
  accounts_in_cookie_jar_info = {/*accounts_are_fresh=*/true, no_accounts,
                                 just_one};
  investigator()->OnAccountsInCookieUpdated(
      accounts_in_cookie_jar_info, GoogleServiceAuthError::AuthErrorNone());
  const AccountRelation expected_relation =
      AccountRelation::NO_SIGNED_IN_SINGLE_SIGNED_OUT_MATCH;
  ExpectSharedReportHistograms(ReportingType::ON_CHANGE, histogram_tester2,
                               nullptr, 0, 1, 1, &expected_relation, true);
}

TEST_F(AccountInvestigatorTest, Initialize) {
  EXPECT_FALSE(*previously_authenticated());
  EXPECT_FALSE(timer()->IsRunning());

  investigator()->Initialize();
  EXPECT_FALSE(*previously_authenticated());
  EXPECT_TRUE(timer()->IsRunning());

  investigator()->Shutdown();
  EXPECT_FALSE(timer()->IsRunning());
}

TEST_F(AccountInvestigatorTest, InitializeSignedIn) {
  identity_test_env()->SetPrimaryAccount("1@mail.com");
  EXPECT_FALSE(*previously_authenticated());

  investigator()->Initialize();
  EXPECT_TRUE(*previously_authenticated());
}

TEST_F(AccountInvestigatorTest, TryPeriodicReportStale) {
  investigator()->Initialize();

  const HistogramTester histogram_tester;
  TryPeriodicReport();
  EXPECT_TRUE(*periodic_pending());
  EXPECT_EQ(0u, histogram_tester.GetTotalCountsForPrefix("Signin.").size());

  std::string email("f@bar.com");
  identity_test_env()->SetCookieAccounts(
      {{email, identity::GetTestGaiaIdForEmail(email)}});

  EXPECT_FALSE(*periodic_pending());
  ExpectSharedReportHistograms(ReportingType::PERIODIC, histogram_tester,
                               nullptr, 1, 0, 1, nullptr, false);
}

TEST_F(AccountInvestigatorTest, TryPeriodicReportEmpty) {
  identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(false);
  const HistogramTester histogram_tester;

  TryPeriodicReport();
  EXPECT_FALSE(*periodic_pending());
  ExpectSharedReportHistograms(ReportingType::PERIODIC, histogram_tester,
                               nullptr, 0, 0, 0, nullptr, false);
}

}  // namespace
