// Copyright (c) 2012 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 <stddef.h>

#include <memory>

#include <set>
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_error_controller_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/sync/profile_sync_test_util.h"
#include "chrome/browser/sync/sync_ui_util.h"
#include "chrome/test/base/testing_profile.h"
#include "components/browser_sync/profile_sync_service_mock.h"
#include "components/signin/core/browser/fake_signin_manager.h"
#include "components/signin/core/browser/profile_oauth2_token_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "google_apis/gaia/oauth2_token_service_delegate.h"
#include "testing/gmock/include/gmock/gmock-actions.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::AtMost;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::ReturnRef;
using ::testing::SetArgPointee;
using ::testing::_;
using browser_sync::ProfileSyncService;
using browser_sync::ProfileSyncServiceMock;
using content::BrowserThread;

// A number of distinct states of the ProfileSyncService can be generated for
// tests.
enum DistinctState {
  STATUS_CASE_SETUP_IN_PROGRESS,
  STATUS_CASE_SETUP_ERROR,
  STATUS_CASE_AUTHENTICATING,
  STATUS_CASE_AUTH_ERROR,
  STATUS_CASE_PROTOCOL_ERROR,
  STATUS_CASE_PASSPHRASE_ERROR,
  STATUS_CASE_CONFIRM_SYNC_SETTINGS,
  STATUS_CASE_SYNCED,
  STATUS_CASE_SYNC_DISABLED_BY_POLICY,
  NUMBER_OF_STATUS_CASES
};

namespace {

const char kTestGaiaId[] = "gaia-id-test_user@test.com";
const char kTestUser[] = "test_user@test.com";

}  // namespace

class SyncUIUtilTest : public testing::Test {
 private:
  content::TestBrowserThreadBundle thread_bundle_;
};

// TODO(tim): This shouldn't be required. r194857 removed the
// AuthInProgress override from FakeSigninManager, which meant this test started
// using the "real" SigninManager AuthInProgress logic. Without that override,
// it's no longer possible to test both chrome os + desktop flows as part of the
// same test, because AuthInProgress is always false on chrome os. Most of the
// tests are unaffected, but STATUS_CASE_AUTHENTICATING can't exist in both
// versions, so it we will require two separate tests, one using SigninManager
// and one using SigninManagerBase (which require different setup procedures.
class FakeSigninManagerForSyncUIUtilTest : public FakeSigninManagerBase {
 public:
  explicit FakeSigninManagerForSyncUIUtilTest(Profile* profile)
      : FakeSigninManagerBase(
            ChromeSigninClientFactory::GetForProfile(profile),
            AccountTrackerServiceFactory::GetForProfile(profile),
            SigninErrorControllerFactory::GetForProfile(profile)),
        auth_in_progress_(false) {
    Initialize(nullptr);
  }

  ~FakeSigninManagerForSyncUIUtilTest() override {}

  bool AuthInProgress() const override { return auth_in_progress_; }

  void set_auth_in_progress() {
    auth_in_progress_ = true;
  }

 private:
  bool auth_in_progress_;
};

// Loads a ProfileSyncServiceMock to emulate one of a number of distinct cases
// in order to perform tests on the generated messages.
void GetDistinctCase(ProfileSyncServiceMock* service,
                     FakeSigninManagerForSyncUIUtilTest* signin,
                     ProfileOAuth2TokenService* token_service,
                     int case_number) {
  // Auth Error object is returned by reference in mock and needs to stay in
  // scope throughout test, so it is owned by calling method. However it is
  // immutable so can only be allocated in this method.
  switch (case_number) {
    case STATUS_CASE_SETUP_IN_PROGRESS: {
      EXPECT_CALL(*service, IsFirstSetupComplete())
          .WillRepeatedly(Return(false));
      EXPECT_CALL(*service, IsSetupInProgress()).WillRepeatedly(Return(true));
      syncer::SyncEngine::Status status;
      EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
          .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
      return;
    }
    case STATUS_CASE_SETUP_ERROR: {
      EXPECT_CALL(*service, IsFirstSetupComplete())
          .WillRepeatedly(Return(false));
      EXPECT_CALL(*service, IsSetupInProgress()).WillRepeatedly(Return(false));
      EXPECT_CALL(*service, GetDisableReasons())
          .WillRepeatedly(
              Return(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR));
      syncer::SyncEngine::Status status;
      EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
          .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
      return;
    }
    case STATUS_CASE_AUTHENTICATING: {
      EXPECT_CALL(*service, IsFirstSetupComplete())
          .WillRepeatedly(Return(true));
      EXPECT_CALL(*service, GetTransportState())
          .WillRepeatedly(Return(syncer::SyncService::TransportState::ACTIVE));
      EXPECT_CALL(*service, IsPassphraseRequired())
          .WillRepeatedly(Return(false));
      syncer::SyncEngine::Status status;
      EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
          .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
      EXPECT_CALL(*service, GetDisableReasons())
          .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
      signin->set_auth_in_progress();
      return;
    }
    case STATUS_CASE_AUTH_ERROR: {
      EXPECT_CALL(*service, IsFirstSetupComplete())
          .WillRepeatedly(Return(true));
      EXPECT_CALL(*service, GetTransportState())
          .WillRepeatedly(Return(syncer::SyncService::TransportState::ACTIVE));
      EXPECT_CALL(*service, IsPassphraseRequired())
          .WillRepeatedly(Return(false));
      syncer::SyncEngine::Status status;
      EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
          .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
      std::string account_id = signin->GetAuthenticatedAccountId();
      token_service->UpdateCredentials(account_id, "refresh_token");
      // TODO(https://crbug.com/836212): Do not use the delegate directly,
      // because it is internal API.
      token_service->GetDelegate()->UpdateAuthError(
          account_id,
          GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_ERROR));
      EXPECT_CALL(*service, GetDisableReasons())
          .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
      return;
    }
    case STATUS_CASE_PROTOCOL_ERROR: {
      EXPECT_CALL(*service, IsFirstSetupComplete())
          .WillRepeatedly(Return(true));
      EXPECT_CALL(*service, GetTransportState())
          .WillRepeatedly(Return(syncer::SyncService::TransportState::ACTIVE));
      EXPECT_CALL(*service, IsPassphraseRequired())
          .WillRepeatedly(Return(false));
      syncer::SyncProtocolError protocolError;
      protocolError.action = syncer::UPGRADE_CLIENT;
      syncer::SyncEngine::Status status;
      status.sync_protocol_error = protocolError;
      EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
          .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
      EXPECT_CALL(*service, GetDisableReasons())
          .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
      return;
    }
    case STATUS_CASE_CONFIRM_SYNC_SETTINGS: {
      EXPECT_CALL(*service, IsPassphraseRequired())
          .WillRepeatedly(Return(false));
      syncer::SyncEngine::Status status;
      EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
          .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
      return;
    }
    case STATUS_CASE_PASSPHRASE_ERROR: {
      EXPECT_CALL(*service, IsFirstSetupComplete())
          .WillRepeatedly(Return(true));
      EXPECT_CALL(*service, GetTransportState())
          .WillRepeatedly(Return(syncer::SyncService::TransportState::ACTIVE));
      syncer::SyncEngine::Status status;
      EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
          .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
      EXPECT_CALL(*service, GetDisableReasons())
          .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
      EXPECT_CALL(*service, IsPassphraseRequired())
          .WillRepeatedly(Return(true));
      EXPECT_CALL(*service, IsPassphraseRequiredForDecryption())
          .WillRepeatedly(Return(true));
      return;
    }
    case STATUS_CASE_SYNCED: {
      EXPECT_CALL(*service, IsFirstSetupComplete())
          .WillRepeatedly(Return(true));
      EXPECT_CALL(*service, GetTransportState())
          .WillRepeatedly(Return(syncer::SyncService::TransportState::ACTIVE));
      EXPECT_CALL(*service, IsPassphraseRequired())
          .WillRepeatedly(Return(false));
      syncer::SyncEngine::Status status;
      EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
          .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
      EXPECT_CALL(*service, GetDisableReasons())
          .WillRepeatedly(Return(syncer::SyncService::DISABLE_REASON_NONE));
      EXPECT_CALL(*service, IsPassphraseRequired())
          .WillRepeatedly(Return(false));
      return;
    }
    case STATUS_CASE_SYNC_DISABLED_BY_POLICY: {
      EXPECT_CALL(*service, GetDisableReasons())
          .WillRepeatedly(
              Return(syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY));
      EXPECT_CALL(*service, IsFirstSetupComplete())
          .WillRepeatedly(Return(false));
      EXPECT_CALL(*service, GetTransportState())
          .WillRepeatedly(
              Return(syncer::SyncService::TransportState::DISABLED));
      EXPECT_CALL(*service, IsPassphraseRequired())
          .WillRepeatedly(Return(false));
      syncer::SyncEngine::Status status;
      EXPECT_CALL(*service, QueryDetailedSyncStatus(_))
          .WillRepeatedly(DoAll(SetArgPointee<0>(status), Return(false)));
      return;
    }
    default:
      NOTREACHED();
  }
}

// Returns the expected value for the output argument |action_type| for each
// of the distinct cases.
sync_ui_util::ActionType GetActionTypeforDistinctCase(int case_number) {
  switch (case_number) {
    case STATUS_CASE_SETUP_IN_PROGRESS:
      return sync_ui_util::NO_ACTION;
    case STATUS_CASE_SETUP_ERROR:
      return sync_ui_util::REAUTHENTICATE;
    case STATUS_CASE_AUTHENTICATING:
      return sync_ui_util::NO_ACTION;
    case STATUS_CASE_AUTH_ERROR:
      return sync_ui_util::REAUTHENTICATE;
    case STATUS_CASE_PROTOCOL_ERROR:
      return sync_ui_util::UPGRADE_CLIENT;
    case STATUS_CASE_PASSPHRASE_ERROR:
      return sync_ui_util::ENTER_PASSPHRASE;
    case STATUS_CASE_CONFIRM_SYNC_SETTINGS:
      return sync_ui_util::CONFIRM_SYNC_SETTINGS;
    case STATUS_CASE_SYNCED:
      return sync_ui_util::NO_ACTION;
    case STATUS_CASE_SYNC_DISABLED_BY_POLICY:
      return sync_ui_util::NO_ACTION;
    default:
      NOTREACHED();
      return sync_ui_util::NO_ACTION;
  }
}

// This test ensures that a each distinctive ProfileSyncService statuses
// will return a unique combination of status and link messages from
// GetStatusLabels().
TEST_F(SyncUIUtilTest, DistinctCasesReportUniqueMessageSets) {
  std::set<base::string16> messages;
  for (int idx = 0; idx != NUMBER_OF_STATUS_CASES; idx++) {
    std::unique_ptr<Profile> profile = std::make_unique<TestingProfile>();
    ProfileSyncService::InitParams init_params =
        CreateProfileSyncServiceParamsForTest(profile.get());
    NiceMock<ProfileSyncServiceMock> service(&init_params);
    GoogleServiceAuthError error = GoogleServiceAuthError::AuthErrorNone();
    EXPECT_CALL(service, GetAuthError()).WillRepeatedly(ReturnRef(error));
    FakeSigninManagerForSyncUIUtilTest signin(profile.get());
    signin.SetAuthenticatedAccountInfo(kTestGaiaId, kTestUser);
    ProfileOAuth2TokenService* token_service =
        ProfileOAuth2TokenServiceFactory::GetForProfile(profile.get());
    GetDistinctCase(&service, &signin, token_service, idx);
    base::string16 status_label;
    base::string16 link_label;
    sync_ui_util::ActionType action_type = sync_ui_util::NO_ACTION;
    sync_ui_util::GetStatusLabels(profile.get(), &service, signin,
                                  &status_label, &link_label, &action_type);

    EXPECT_EQ(GetActionTypeforDistinctCase(idx), action_type);
    // If the status and link message combination is already present in the set
    // of messages already seen, this is a duplicate rather than a unique
    // message, and the test has failed.
    EXPECT_FALSE(status_label.empty()) <<
        "Empty status label returned for case #" << idx;
    // Ensures a search for string 'href' (found in links, not a string to be
    // found in an English language message) fails, since links are excluded
    // from the status label.
    EXPECT_EQ(status_label.find(base::ASCIIToUTF16("href")),
              base::string16::npos);
    base::string16 combined_label =
        status_label + base::ASCIIToUTF16("#") + link_label;
    EXPECT_TRUE(messages.find(combined_label) == messages.end()) <<
        "Duplicate message for case #" << idx << ": " << combined_label;
    messages.insert(combined_label);
    testing::Mock::VerifyAndClearExpectations(&service);
    testing::Mock::VerifyAndClearExpectations(&signin);
    EXPECT_CALL(service, GetAuthError()).WillRepeatedly(ReturnRef(error));
    signin.Shutdown();
  }
}

TEST_F(SyncUIUtilTest, UnrecoverableErrorWithActionableError) {
  std::unique_ptr<Profile> profile(MakeSignedInTestingProfile());
  SigninManagerBase* signin =
      SigninManagerFactory::GetForProfile(profile.get());

  ProfileSyncServiceMock service(
      CreateProfileSyncServiceParamsForTest(profile.get()));
  EXPECT_CALL(service, IsFirstSetupComplete()).WillRepeatedly(Return(true));
  EXPECT_CALL(service, GetDisableReasons())
      .WillRepeatedly(
          Return(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR));

  // First time action is not set. We should get unrecoverable error.
  syncer::SyncStatus status;
  EXPECT_CALL(service, QueryDetailedSyncStatus(_))
      .WillOnce(DoAll(SetArgPointee<0>(status), Return(true)));

  base::string16 link_label;
  base::string16 unrecoverable_error_status_label;
  sync_ui_util::ActionType action_type = sync_ui_util::NO_ACTION;
  sync_ui_util::GetStatusLabels(profile.get(), &service, *signin,
                                &unrecoverable_error_status_label, &link_label,
                                &action_type);

  // Expect the generic unrecoverable error action which is to reauthenticate.
  EXPECT_EQ(sync_ui_util::REAUTHENTICATE, action_type);

  // This time set action to UPGRADE_CLIENT. Ensure that status label differs
  // from previous one.
  status.sync_protocol_error.action = syncer::UPGRADE_CLIENT;
  EXPECT_CALL(service, QueryDetailedSyncStatus(_))
      .WillOnce(DoAll(SetArgPointee<0>(status), Return(true)));
  base::string16 upgrade_client_status_label;
  sync_ui_util::GetStatusLabels(profile.get(), &service, *signin,
                                &upgrade_client_status_label, &link_label,
                                &action_type);
  // Expect an explicit 'client upgrade' action.
  EXPECT_EQ(sync_ui_util::UPGRADE_CLIENT, action_type);

  EXPECT_NE(unrecoverable_error_status_label, upgrade_client_status_label);
}

TEST_F(SyncUIUtilTest, ActionableErrorWithPassiveMessage) {
  std::unique_ptr<Profile> profile(MakeSignedInTestingProfile());
  SigninManagerBase* signin =
      SigninManagerFactory::GetForProfile(profile.get());

  ProfileSyncServiceMock service(
      CreateProfileSyncServiceParamsForTest(profile.get()));
  EXPECT_CALL(service, IsFirstSetupComplete()).WillRepeatedly(Return(true));
  EXPECT_CALL(service, GetDisableReasons())
      .WillRepeatedly(
          Return(syncer::SyncService::DISABLE_REASON_UNRECOVERABLE_ERROR));

  // Set action to UPGRADE_CLIENT.
  syncer::SyncStatus status;
  status.sync_protocol_error.action = syncer::UPGRADE_CLIENT;
  EXPECT_CALL(service, QueryDetailedSyncStatus(_))
      .WillOnce(DoAll(SetArgPointee<0>(status), Return(true)));

  base::string16 first_actionable_error_status_label;
  base::string16 link_label;
  sync_ui_util::ActionType action_type = sync_ui_util::NO_ACTION;
  sync_ui_util::GetStatusLabels(profile.get(), &service, *signin,
                                &first_actionable_error_status_label,
                                &link_label, &action_type);
  // Expect a 'client upgrade' call to action.
  EXPECT_EQ(sync_ui_util::UPGRADE_CLIENT, action_type);

  // This time set action to ENABLE_SYNC_ON_ACCOUNT.
  status.sync_protocol_error.action = syncer::ENABLE_SYNC_ON_ACCOUNT;
  EXPECT_CALL(service, QueryDetailedSyncStatus(_))
      .WillOnce(DoAll(SetArgPointee<0>(status), Return(true)));

  base::string16 second_actionable_error_status_label;
  action_type = sync_ui_util::NO_ACTION;
  sync_ui_util::GetStatusLabels(profile.get(), &service, *signin,
                                &second_actionable_error_status_label,
                                &link_label, &action_type);
  // Expect a passive message instead of a call to action.
  EXPECT_EQ(sync_ui_util::NO_ACTION, action_type);

  EXPECT_NE(first_actionable_error_status_label,
            second_actionable_error_status_label);
}

TEST_F(SyncUIUtilTest, SyncSettingsConfirmationNeededTest) {
  std::unique_ptr<Profile> profile(MakeSignedInTestingProfile());
  SigninManagerBase* signin =
      SigninManagerFactory::GetForProfile(profile.get());

  NiceMock<ProfileSyncServiceMock> service(
      CreateProfileSyncServiceParamsForTest(profile.get()));
  ASSERT_TRUE(service.IsSyncConfirmationNeeded());

  base::string16 actionable_error_status_label;
  base::string16 link_label;
  sync_ui_util::ActionType action_type = sync_ui_util::NO_ACTION;

  sync_ui_util::GetStatusLabels(profile.get(), &service, *signin,
                                &actionable_error_status_label, &link_label,
                                &action_type);

  EXPECT_EQ(action_type, sync_ui_util::CONFIRM_SYNC_SETTINGS);
}
