// Copyright 2015 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 "chrome/browser/password_manager/password_store_mac.h"

#include <utility>

#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/scoped_observer.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/histogram_tester.h"
#include "chrome/browser/prefs/browser_prefs.h"
#include "components/os_crypt/os_crypt_mocker.h"
#include "components/password_manager/core/browser/login_database.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/password_store_consumer.h"
#include "components/password_manager/core/common/password_manager_pref_names.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

using autofill::PasswordForm;
using content::BrowserThread;
using password_manager::MigrationStatus;
using password_manager::PasswordStore;
using password_manager::PasswordStoreChange;
using password_manager::PasswordStoreChangeList;
using testing::_;
using testing::ElementsAre;
using testing::IsEmpty;
using testing::Pointee;

class MockPasswordStoreConsumer
    : public password_manager::PasswordStoreConsumer {
 public:
  MockPasswordStoreConsumer() = default;

  void WaitForResult() {
    base::RunLoop run_loop;
    nested_loop_ = &run_loop;
    run_loop.Run();
    nested_loop_ = nullptr;
  }

  const std::vector<std::unique_ptr<PasswordForm>>& forms() const {
    return forms_;
  }

 private:
  void OnGetPasswordStoreResults(
      std::vector<std::unique_ptr<PasswordForm>> results) override {
    forms_.swap(results);
    if (nested_loop_)
      nested_loop_->Quit();
  }

  std::vector<std::unique_ptr<PasswordForm>> forms_;
  base::RunLoop* nested_loop_ = nullptr;

  DISALLOW_COPY_AND_ASSIGN(MockPasswordStoreConsumer);
};

class MockPasswordStoreObserver
    : public password_manager::PasswordStore::Observer {
 public:
  explicit MockPasswordStoreObserver(PasswordStoreMac* password_store)
      : guard_(this) {
    guard_.Add(password_store);
  }
  MOCK_METHOD1(OnLoginsChanged,
               void(const password_manager::PasswordStoreChangeList& changes));

 private:
  ScopedObserver<PasswordStoreMac, MockPasswordStoreObserver> guard_;

  DISALLOW_COPY_AND_ASSIGN(MockPasswordStoreObserver);
};

// A mock LoginDatabase that simulates a failing Init() method.
class BadLoginDatabase : public password_manager::LoginDatabase {
 public:
  BadLoginDatabase() : password_manager::LoginDatabase(base::FilePath()) {}
  ~BadLoginDatabase() override {}

  // LoginDatabase:
  bool Init() override { return false; }

 private:
  DISALLOW_COPY_AND_ASSIGN(BadLoginDatabase);
};

class PasswordStoreMacTest : public testing::TestWithParam<MigrationStatus> {
 public:
  PasswordStoreMacTest();
  ~PasswordStoreMacTest() override;

  void CreateAndInitPasswordStore(
      std::unique_ptr<password_manager::LoginDatabase> login_db);

  void ClosePasswordStore();

  // Do a store-level query to wait for all the previously enqueued operations
  // to finish.
  void FinishAsyncProcessing();

  // Add/Update/Remove |form| and verify the operation succeeded.
  void AddForm(const PasswordForm& form);
  void UpdateForm(const PasswordForm& form);
  void RemoveForm(const PasswordForm& form);

  base::FilePath test_login_db_file_path() const;

  // Returns the expected migration status after the password store was inited.
  MigrationStatus GetTargetStatus() const;

  password_manager::LoginDatabase* login_db() const {
    return store_->login_metadata_db();
  }

  PasswordStoreMac* store() { return store_.get(); }

 protected:
  content::TestBrowserThreadBundle ui_thread_;

  base::ScopedTempDir db_dir_;
  scoped_refptr<PasswordStoreMac> store_;
  sync_preferences::TestingPrefServiceSyncable testing_prefs_;
};

PasswordStoreMacTest::PasswordStoreMacTest() {
  EXPECT_TRUE(db_dir_.CreateUniqueTempDir());
  chrome::RegisterUserProfilePrefs(testing_prefs_.registry());
  testing_prefs_.SetInteger(password_manager::prefs::kKeychainMigrationStatus,
                            static_cast<int>(GetParam()));
  // Ensure that LoginDatabase will use the mock keychain if it needs to
  // encrypt/decrypt a password.
  OSCryptMocker::SetUpWithSingleton();
}

PasswordStoreMacTest::~PasswordStoreMacTest() {
  ClosePasswordStore();
  OSCryptMocker::TearDown();
}

void PasswordStoreMacTest::CreateAndInitPasswordStore(
    std::unique_ptr<password_manager::LoginDatabase> login_db) {
  store_ = new PasswordStoreMac(
      BrowserThread::GetTaskRunnerForThread(BrowserThread::UI),
      std::move(login_db), &testing_prefs_);
  ASSERT_TRUE(store_->Init(syncer::SyncableService::StartSyncFlare(), nullptr));
}

void PasswordStoreMacTest::ClosePasswordStore() {
  if (!store_)
    return;
  store_->ShutdownOnUIThread();
  EXPECT_FALSE(store_->GetBackgroundTaskRunner());
  store_ = nullptr;
}

void PasswordStoreMacTest::FinishAsyncProcessing() {
  // Do a store-level query to wait for all the previously enqueued operations
  // to finish.
  MockPasswordStoreConsumer consumer;
  store_->GetLogins({PasswordForm::SCHEME_HTML, std::string(), GURL()},
                    &consumer);
  consumer.WaitForResult();
}

base::FilePath PasswordStoreMacTest::test_login_db_file_path() const {
  return db_dir_.GetPath().Append(FILE_PATH_LITERAL("login.db"));
}

MigrationStatus PasswordStoreMacTest::GetTargetStatus() const {
  if (GetParam() == MigrationStatus::NOT_STARTED ||
      GetParam() == MigrationStatus::FAILED_ONCE ||
      GetParam() == MigrationStatus::FAILED_TWICE) {
    return MigrationStatus::MIGRATION_STOPPED;
  }
  return GetParam();
}

void PasswordStoreMacTest::AddForm(const PasswordForm& form) {
  MockPasswordStoreObserver mock_observer(store());

  password_manager::PasswordStoreChangeList list;
  list.push_back(password_manager::PasswordStoreChange(
      password_manager::PasswordStoreChange::ADD, form));
  EXPECT_CALL(mock_observer, OnLoginsChanged(list));
  store()->AddLogin(form);
  FinishAsyncProcessing();
}

void PasswordStoreMacTest::UpdateForm(const PasswordForm& form) {
  MockPasswordStoreObserver mock_observer(store());

  password_manager::PasswordStoreChangeList list;
  list.push_back(password_manager::PasswordStoreChange(
      password_manager::PasswordStoreChange::UPDATE, form));
  EXPECT_CALL(mock_observer, OnLoginsChanged(list));
  store()->UpdateLogin(form);
  FinishAsyncProcessing();
}

void PasswordStoreMacTest::RemoveForm(const PasswordForm& form) {
  MockPasswordStoreObserver mock_observer(store());

  password_manager::PasswordStoreChangeList list;
  list.push_back(password_manager::PasswordStoreChange(
      password_manager::PasswordStoreChange::REMOVE, form));
  EXPECT_CALL(mock_observer, OnLoginsChanged(list));
  store()->RemoveLogin(form);
  FinishAsyncProcessing();
}

// ----------- Tests -------------

TEST_P(PasswordStoreMacTest, Sanity) {
  base::HistogramTester histogram_tester;

  CreateAndInitPasswordStore(base::MakeUnique<password_manager::LoginDatabase>(
      test_login_db_file_path()));
  FinishAsyncProcessing();
  ClosePasswordStore();

  int status = testing_prefs_.GetInteger(
      password_manager::prefs::kKeychainMigrationStatus);
  EXPECT_EQ(static_cast<int>(GetTargetStatus()), status);
  histogram_tester.ExpectUniqueSample(
      "PasswordManager.KeychainMigration.Status", status, 1);
}

TEST_P(PasswordStoreMacTest, StartAndStop) {
  base::HistogramTester histogram_tester;
  // PasswordStore::ShutdownOnUIThread() immediately follows
  // PasswordStore::Init(). The message loop isn't running in between. Anyway,
  // PasswordStore should not collapse.
  CreateAndInitPasswordStore(base::MakeUnique<password_manager::LoginDatabase>(
      test_login_db_file_path()));
  ClosePasswordStore();

  histogram_tester.ExpectUniqueSample(
      "PasswordManager.KeychainMigration.Status",
      static_cast<int>(GetTargetStatus()), 1);
}

TEST_P(PasswordStoreMacTest, OperationsOnABadDatabaseSilentlyFail) {
  // Verify that operations on a PasswordStore with a bad database cause no
  // explosions, but fail without side effect, return no data and trigger no
  // notifications.
  CreateAndInitPasswordStore(base::MakeUnique<BadLoginDatabase>());
  FinishAsyncProcessing();
  EXPECT_FALSE(login_db());

  // The store should outlive the observer.
  scoped_refptr<PasswordStoreMac> store_refptr = store();
  MockPasswordStoreObserver mock_observer(store());
  EXPECT_CALL(mock_observer, OnLoginsChanged(_)).Times(0);

  // Add a new autofillable login + a blacklisted login.
  password_manager::PasswordFormData www_form_data = {
      PasswordForm::SCHEME_HTML,
      "http://www.facebook.com/",
      "http://www.facebook.com/index.html",
      "login",
      L"username",
      L"password",
      L"submit",
      L"not_joe_user",
      L"12345",
      true,
      1};
  std::unique_ptr<PasswordForm> form =
      CreatePasswordFormFromDataForTesting(www_form_data);
  std::unique_ptr<PasswordForm> blacklisted_form(new PasswordForm(*form));
  blacklisted_form->signon_realm = "http://foo.example.com";
  blacklisted_form->origin = GURL("http://foo.example.com/origin");
  blacklisted_form->action = GURL("http://foo.example.com/action");
  blacklisted_form->blacklisted_by_user = true;
  store()->AddLogin(*form);
  store()->AddLogin(*blacklisted_form);
  FinishAsyncProcessing();

  // Get all logins; autofillable logins; blacklisted logins.
  MockPasswordStoreConsumer mock_consumer;
  store()->GetLogins(PasswordStore::FormDigest(*form), &mock_consumer);
  mock_consumer.WaitForResult();
  EXPECT_THAT(mock_consumer.forms(), IsEmpty());

  store()->GetAutofillableLogins(&mock_consumer);
  mock_consumer.WaitForResult();
  EXPECT_THAT(mock_consumer.forms(), IsEmpty());

  store()->GetBlacklistLogins(&mock_consumer);
  mock_consumer.WaitForResult();
  EXPECT_THAT(mock_consumer.forms(), IsEmpty());

  // Report metrics.
  store()->ReportMetrics("Test Username", true);
  FinishAsyncProcessing();

  // Change the login.
  form->password_value = base::ASCIIToUTF16("a different password");
  store()->UpdateLogin(*form);
  FinishAsyncProcessing();

  // Delete one login; a range of logins.
  store()->RemoveLogin(*form);
  store()->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max(),
                                      base::Closure());
  store()->RemoveLoginsSyncedBetween(base::Time(), base::Time::Max());
  FinishAsyncProcessing();

  // Verify no notifications are fired during shutdown either.
  ClosePasswordStore();
}

INSTANTIATE_TEST_CASE_P(,
                        PasswordStoreMacTest,
                        testing::Values(MigrationStatus::NOT_STARTED,
                                        MigrationStatus::MIGRATED,
                                        MigrationStatus::FAILED_ONCE,
                                        MigrationStatus::FAILED_TWICE,
                                        MigrationStatus::MIGRATED_DELETED,
                                        MigrationStatus::MIGRATED_PARTIALLY,
                                        MigrationStatus::MIGRATION_STOPPED));

}  // namespace
