// 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 <stddef.h>

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind_test_util.h"
#include "base/test/mock_callback.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/passwords_private/passwords_private_delegate_impl.h"
#include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router.h"
#include "chrome/browser/extensions/api/passwords_private/passwords_private_event_router_factory.h"
#include "chrome/browser/password_manager/password_store_factory.h"
#include "chrome/test/base/testing_profile.h"
#include "components/autofill/core/common/password_form.h"
#include "components/password_manager/core/browser/password_list_sorter.h"
#include "components/password_manager/core/browser/password_manager_test_utils.h"
#include "components/password_manager/core/browser/test_password_store.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/browser/test_event_router.h"
#include "testing/gtest/include/gtest/gtest.h"

using PasswordFormList = std::vector<std::unique_ptr<autofill::PasswordForm>>;
using ::testing::Ne;
using ::testing::StrictMock;

namespace extensions {

namespace {

template <typename T>
base::OnceCallback<void(T)> GetCallbackArgument(T* arg) {
  return base::BindOnce([](T* arg, T value) { *arg = std::move(value); },
                        base::Unretained(arg));
}

template <typename T>
class CallbackTracker {
 public:
  CallbackTracker()
      : callback_(base::BindRepeating(&CallbackTracker::Callback,
                                      base::Unretained(this))) {}

  using TypedCallback = base::RepeatingCallback<void(const T&)>;

  const TypedCallback& callback() const { return callback_; }

  size_t call_count() const { return call_count_; }

 private:
  void Callback(const T& args) {
    EXPECT_FALSE(args.empty());
    ++call_count_;
  }

  size_t call_count_ = 0;

  TypedCallback callback_;

  DISALLOW_COPY_AND_ASSIGN(CallbackTracker);
};

class PasswordEventObserver
    : public extensions::TestEventRouter::EventObserver {
 public:
  // The observer will only listen to events with the |event_name|.
  explicit PasswordEventObserver(const std::string& event_name);

  ~PasswordEventObserver() override;

  // Removes |event_args_| from |*this| and returns them.
  base::Value PassEventArgs();

  // extensions::TestEventRouter::EventObserver:
  void OnBroadcastEvent(const extensions::Event& event) override;

 private:
  // The name of the observed event.
  const std::string event_name_;

  // The arguments passed for the last observed event.
  base::Value event_args_;

  DISALLOW_COPY_AND_ASSIGN(PasswordEventObserver);
};

PasswordEventObserver::PasswordEventObserver(const std::string& event_name)
    : event_name_(event_name) {}

PasswordEventObserver::~PasswordEventObserver() = default;

base::Value PasswordEventObserver::PassEventArgs() {
  return std::move(event_args_);
}

void PasswordEventObserver::OnBroadcastEvent(const extensions::Event& event) {
  if (event.event_name != event_name_) {
    return;
  }
  event_args_ = event.event_args->Clone();
}

enum class ReauthResult { PASS, FAIL };

bool FakeOsReauthCall(bool* reauth_called,
                      ReauthResult result,
                      password_manager::ReauthPurpose purpose) {
  *reauth_called = true;
  return result == ReauthResult::PASS;
}

std::unique_ptr<KeyedService> BuildPasswordsPrivateEventRouter(
    content::BrowserContext* context) {
  return std::unique_ptr<KeyedService>(
      PasswordsPrivateEventRouter::Create(context));
}

autofill::PasswordForm CreateSampleForm() {
  autofill::PasswordForm form;
  form.origin = GURL("http://abc1.com");
  form.username_value = base::ASCIIToUTF16("test@gmail.com");
  form.password_value = base::ASCIIToUTF16("test");
  return form;
}

}  // namespace

class PasswordsPrivateDelegateImplTest : public testing::Test {
 public:
  PasswordsPrivateDelegateImplTest();
  ~PasswordsPrivateDelegateImplTest() override;

  // Sets up a testing password store and fills it with |forms|.
  void SetUpPasswordStore(std::vector<autofill::PasswordForm> forms);

  // Sets up a testing EventRouter with a production
  // PasswordsPrivateEventRouter.
  void SetUpRouters();

 protected:
  content::BrowserTaskEnvironment task_environment_;
  TestingProfile profile_;
  extensions::TestEventRouter* event_router_ = nullptr;

 private:
  DISALLOW_COPY_AND_ASSIGN(PasswordsPrivateDelegateImplTest);
};

PasswordsPrivateDelegateImplTest::PasswordsPrivateDelegateImplTest() = default;

PasswordsPrivateDelegateImplTest::~PasswordsPrivateDelegateImplTest() = default;

void PasswordsPrivateDelegateImplTest::SetUpPasswordStore(
    std::vector<autofill::PasswordForm> forms) {
  scoped_refptr<password_manager::TestPasswordStore> password_store(
      static_cast<password_manager::TestPasswordStore*>(
          PasswordStoreFactory::GetInstance()
              ->SetTestingFactoryAndUse(
                  &profile_,
                  base::BindRepeating(&password_manager::BuildPasswordStore<
                                      content::BrowserContext,
                                      password_manager::TestPasswordStore>))
              .get()));
  for (const autofill::PasswordForm& form : forms) {
    password_store->AddLogin(form);
  }
  // Spin the loop to allow PasswordStore tasks being processed.
  base::RunLoop().RunUntilIdle();
}

void PasswordsPrivateDelegateImplTest::SetUpRouters() {
  event_router_ = extensions::CreateAndUseTestEventRouter(&profile_);
  // Set the production PasswordsPrivateEventRouter::Create as a testing
  // factory, because at some point during the preceding initialization, a null
  // factory is set, resulting in nul PasswordsPrivateEventRouter.
  PasswordsPrivateEventRouterFactory::GetInstance()->SetTestingFactory(
      &profile_, base::BindRepeating(&BuildPasswordsPrivateEventRouter));
}

TEST_F(PasswordsPrivateDelegateImplTest, GetSavedPasswordsList) {
  CallbackTracker<PasswordsPrivateDelegate::UiEntries> tracker;

  PasswordsPrivateDelegateImpl delegate(&profile_);

  delegate.GetSavedPasswordsList(tracker.callback());
  EXPECT_EQ(0u, tracker.call_count());

  PasswordFormList list;
  list.push_back(std::make_unique<autofill::PasswordForm>());
  delegate.SetPasswordList(list);
  EXPECT_EQ(1u, tracker.call_count());

  delegate.GetSavedPasswordsList(tracker.callback());
  EXPECT_EQ(2u, tracker.call_count());
}

TEST_F(PasswordsPrivateDelegateImplTest, GetPasswordExceptionsList) {
  CallbackTracker<PasswordsPrivateDelegate::ExceptionEntries> tracker;

  PasswordsPrivateDelegateImpl delegate(&profile_);

  delegate.GetPasswordExceptionsList(tracker.callback());
  EXPECT_EQ(0u, tracker.call_count());

  PasswordFormList list;
  list.push_back(std::make_unique<autofill::PasswordForm>());
  delegate.SetPasswordExceptionList(list);
  EXPECT_EQ(1u, tracker.call_count());

  delegate.GetPasswordExceptionsList(tracker.callback());
  EXPECT_EQ(2u, tracker.call_count());
}

TEST_F(PasswordsPrivateDelegateImplTest, ChangeSavedPassword) {
  autofill::PasswordForm sample_form = CreateSampleForm();
  SetUpPasswordStore({sample_form});

  PasswordsPrivateDelegateImpl delegate(&profile_);
  // Spin the loop to allow PasswordStore tasks posted on the creation of
  // |delegate| to be completed.
  base::RunLoop().RunUntilIdle();

  // Double check that the contents of the passwords list matches our
  // expectation.
  bool got_passwords = false;
  delegate.GetSavedPasswordsList(base::BindLambdaForTesting(
      [&](const PasswordsPrivateDelegate::UiEntries& password_list) {
        got_passwords = true;
        ASSERT_EQ(1u, password_list.size());
        EXPECT_EQ(sample_form.username_value,
                  base::UTF8ToUTF16(password_list[0].username));
        EXPECT_EQ(sample_form.password_value.size(),
                  size_t{password_list[0].num_characters_in_password});
      }));
  EXPECT_TRUE(got_passwords);

  int sample_form_id = delegate.GetPasswordIdGeneratorForTesting().GenerateId(
      password_manager::CreateSortKey(sample_form));
  delegate.ChangeSavedPassword(sample_form_id, base::ASCIIToUTF16("new_user"),
                               base::ASCIIToUTF16("new_pass"));

  // Spin the loop to allow PasswordStore tasks posted when changing the
  // password to be completed.
  base::RunLoop().RunUntilIdle();

  // Check that the changing the password got reflected in the passwords list.
  got_passwords = false;
  delegate.GetSavedPasswordsList(base::BindLambdaForTesting(
      [&](const PasswordsPrivateDelegate::UiEntries& password_list) {
        got_passwords = true;
        ASSERT_EQ(1u, password_list.size());
        EXPECT_EQ(base::ASCIIToUTF16("new_user"),
                  base::UTF8ToUTF16(password_list[0].username));
        EXPECT_EQ(base::ASCIIToUTF16("new_pass").size(),
                  size_t{password_list[0].num_characters_in_password});
      }));
  EXPECT_TRUE(got_passwords);
}

TEST_F(PasswordsPrivateDelegateImplTest, TestPassedReauthOnView) {
  SetUpPasswordStore({CreateSampleForm()});

  PasswordsPrivateDelegateImpl delegate(&profile_);
  // Spin the loop to allow PasswordStore tasks posted on the creation of
  // |delegate| to be completed.
  base::RunLoop().RunUntilIdle();

  bool reauth_called = false;
  delegate.SetOsReauthCallForTesting(base::BindRepeating(
      &FakeOsReauthCall, &reauth_called, ReauthResult::PASS));

  base::Optional<base::string16> plaintext_password;
  delegate.RequestShowPassword(0, GetCallbackArgument(&plaintext_password),
                               nullptr);
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(reauth_called);
  EXPECT_TRUE(plaintext_password.has_value());
  EXPECT_EQ(base::ASCIIToUTF16("test"), *plaintext_password);
}

TEST_F(PasswordsPrivateDelegateImplTest, TestFailedReauthOnView) {
  SetUpPasswordStore({CreateSampleForm()});

  PasswordsPrivateDelegateImpl delegate(&profile_);
  // Spin the loop to allow PasswordStore tasks posted on the creation of
  // |delegate| to be completed.
  base::RunLoop().RunUntilIdle();

  bool reauth_called = false;
  delegate.SetOsReauthCallForTesting(base::BindRepeating(
      &FakeOsReauthCall, &reauth_called, ReauthResult::FAIL));

  base::Optional<base::string16> plaintext_password;
  delegate.RequestShowPassword(0, GetCallbackArgument(&plaintext_password),
                               nullptr);
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(reauth_called);
  EXPECT_FALSE(plaintext_password.has_value());
}

TEST_F(PasswordsPrivateDelegateImplTest, TestReauthOnExport) {
  SetUpPasswordStore({CreateSampleForm()});
  StrictMock<base::MockCallback<base::OnceCallback<void(const std::string&)>>>
      mock_accepted;

  PasswordsPrivateDelegateImpl delegate(&profile_);
  // Spin the loop to allow PasswordStore tasks posted on the creation of
  // |delegate| to be completed.
  base::RunLoop().RunUntilIdle();

  bool reauth_called = false;
  delegate.SetOsReauthCallForTesting(base::BindRepeating(
      &FakeOsReauthCall, &reauth_called, ReauthResult::PASS));

  EXPECT_CALL(mock_accepted, Run(std::string())).Times(2);

  delegate.ExportPasswords(mock_accepted.Get(), nullptr);
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(reauth_called);

  // Export should ignore previous reauthentication results.
  reauth_called = false;
  delegate.ExportPasswords(mock_accepted.Get(), nullptr);
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(reauth_called);
}

TEST_F(PasswordsPrivateDelegateImplTest, TestReauthFailedOnExport) {
  SetUpPasswordStore({CreateSampleForm()});
  StrictMock<base::MockCallback<base::OnceCallback<void(const std::string&)>>>
      mock_accepted;

  PasswordsPrivateDelegateImpl delegate(&profile_);
  // Spin the loop to allow PasswordStore tasks posted on the creation of
  // |delegate| to be completed.
  base::RunLoop().RunUntilIdle();

  EXPECT_CALL(mock_accepted, Run(std::string("reauth-failed")));

  bool reauth_called = false;
  delegate.SetOsReauthCallForTesting(base::BindRepeating(
      &FakeOsReauthCall, &reauth_called, ReauthResult::FAIL));

  delegate.ExportPasswords(mock_accepted.Get(), nullptr);
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(reauth_called);
}

}  // namespace extensions
