// 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 <utility>

#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/content/common/test_autofill_types.mojom.h"
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/core/common/password_generation_util.h"
#include "components/autofill/core/common/signatures_util.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace autofill {

const std::vector<const char*> kOptions = {"Option1", "Option2", "Option3",
                                           "Option4"};
namespace {

void CreateTestFieldDataPredictions(const std::string& signature,
                                    FormFieldDataPredictions* field_predict) {
  test::CreateTestSelectField("TestLabel", "TestName", "TestValue", kOptions,
                              kOptions, 4, &field_predict->field);
  field_predict->signature = signature;
  field_predict->heuristic_type = "TestSignature";
  field_predict->server_type = "TestServerType";
  field_predict->overall_type = "TestOverallType";
  field_predict->parseable_name = "TestParseableName";
  field_predict->section = "TestSection";
}

void CreateTestPasswordFormFillData(PasswordFormFillData* fill_data) {
  fill_data->form_renderer_id = 1234;
  fill_data->origin = GURL("https://foo.com/");
  fill_data->action = GURL("https://foo.com/login");
  test::CreateTestSelectField("TestUsernameFieldLabel", "TestUsernameFieldName",
                              "TestUsernameFieldValue", kOptions, kOptions, 4,
                              &fill_data->username_field);
  test::CreateTestSelectField("TestPasswordFieldLabel", "TestPasswordFieldName",
                              "TestPasswordFieldValue", kOptions, kOptions, 4,
                              &fill_data->password_field);
  fill_data->preferred_realm = "https://foo.com/";

  base::string16 name;
  PasswordAndRealm pr;
  name = base::ASCIIToUTF16("Tom");
  pr.password = base::ASCIIToUTF16("Tom_Password");
  pr.realm = "https://foo.com/";
  fill_data->additional_logins[name] = pr;
  name = base::ASCIIToUTF16("Jerry");
  pr.password = base::ASCIIToUTF16("Jerry_Password");
  pr.realm = "https://bar.com/";
  fill_data->additional_logins[name] = pr;

  fill_data->wait_for_username = true;
}

void CreateTestPasswordForm(PasswordForm* form) {
  form->scheme = PasswordForm::Scheme::SCHEME_HTML;
  form->signon_realm = "https://foo.com/";
  form->origin = GURL("https://foo.com/");
  form->action = GURL("https://foo.com/login");
  form->affiliated_web_realm = "https://foo.com/";
  form->submit_element = base::ASCIIToUTF16("test_submit");
  form->username_element = base::ASCIIToUTF16("username");
  form->username_marked_by_site = true;
  form->username_value = base::ASCIIToUTF16("test@gmail.com");
  form->other_possible_usernames.push_back(ValueElementPair(
      base::ASCIIToUTF16("Jerry_1"), base::ASCIIToUTF16("id1")));
  form->other_possible_usernames.push_back(ValueElementPair(
      base::ASCIIToUTF16("Jerry_2"), base::ASCIIToUTF16("id2")));
  form->all_possible_passwords.push_back(
      ValueElementPair(base::ASCIIToUTF16("pass1"), base::ASCIIToUTF16("el1")));
  form->all_possible_passwords.push_back(
      ValueElementPair(base::ASCIIToUTF16("pass2"), base::ASCIIToUTF16("el2")));
  form->form_has_autofilled_value = true;
  form->password_element = base::ASCIIToUTF16("password");
  form->password_value = base::ASCIIToUTF16("test");
  form->new_password_element = base::ASCIIToUTF16("new_password");
  form->new_password_value = base::ASCIIToUTF16("new_password_value");
  form->new_password_marked_by_site = false;
  form->new_password_element = base::ASCIIToUTF16("confirmation_password");
  form->preferred = false;
  form->date_created = base::Time::Now();
  form->date_synced = base::Time::Now();
  form->blacklisted_by_user = false;
  form->type = PasswordForm::Type::TYPE_GENERATED;
  form->times_used = 999;
  test::CreateTestAddressFormData(&form->form_data);
  form->generation_upload_status =
      PasswordForm::GenerationUploadStatus::POSITIVE_SIGNAL_SENT;
  form->display_name = base::ASCIIToUTF16("test display name");
  form->icon_url = GURL("https://foo.com/icon.png");
  form->federation_origin = url::Origin::Create(GURL("http://wwww.google.com"));
  form->skip_zero_click = false;
  form->was_parsed_using_autofill_predictions = false;
  form->is_public_suffix_match = true;
  form->is_affiliation_based_match = true;
  form->submission_event = SubmissionIndicatorEvent::SAME_DOCUMENT_NAVIGATION;
}

void CreateTestFormsPredictionsMap(FormsPredictionsMap* predictions) {
  FormsPredictionsMap& result_map = *predictions;
  // 1st element.
  FormData form_data;
  test::CreateTestAddressFormData(&form_data);
  ASSERT_TRUE(form_data.fields.size() >= 4);
  result_map[form_data][form_data.fields[0]] =
      PasswordFormFieldPredictionType::PREDICTION_USERNAME;
  result_map[form_data][form_data.fields[1]] =
      PasswordFormFieldPredictionType::PREDICTION_CURRENT_PASSWORD;
  result_map[form_data][form_data.fields[2]] =
      PasswordFormFieldPredictionType::PREDICTION_NEW_PASSWORD;
  result_map[form_data][form_data.fields[3]] =
      PasswordFormFieldPredictionType::PREDICTION_NOT_PASSWORD;

  // 2nd element.
  form_data.fields.clear();
  result_map[form_data] =
      std::map<FormFieldData, PasswordFormFieldPredictionType>();

  // 3rd element.
  FormFieldData field_data;
  test::CreateTestSelectField("TestLabel1", "TestName1", "TestValue1", kOptions,
                              kOptions, 4, &field_data);
  form_data.fields.push_back(field_data);
  test::CreateTestSelectField("TestLabel2", "TestName2", "TestValue2", kOptions,
                              kOptions, 4, &field_data);
  form_data.fields.push_back(field_data);
  result_map[form_data][form_data.fields[0]] =
      PasswordFormFieldPredictionType::PREDICTION_NEW_PASSWORD;
  result_map[form_data][form_data.fields[1]] =
      PasswordFormFieldPredictionType::PREDICTION_CURRENT_PASSWORD;
}

void CreatePasswordGenerationUIData(
    password_generation::PasswordGenerationUIData* data) {
  data->bounds = gfx::RectF(1, 1, 200, 100);
  data->max_length = 20;
  data->generation_element = base::ASCIIToUTF16("generation_element");
  data->text_direction = base::i18n::RIGHT_TO_LEFT;
  CreateTestPasswordForm(&data->password_form);
}

void CheckEqualPasswordFormFillData(const PasswordFormFillData& expected,
                                    const PasswordFormFillData& actual) {
  EXPECT_EQ(expected.form_renderer_id, actual.form_renderer_id);
  EXPECT_EQ(expected.origin, actual.origin);
  EXPECT_EQ(expected.action, actual.action);
  EXPECT_EQ(expected.username_field, actual.username_field);
  EXPECT_EQ(expected.password_field, actual.password_field);
  EXPECT_EQ(expected.preferred_realm, actual.preferred_realm);

  {
    EXPECT_EQ(expected.additional_logins.size(),
              actual.additional_logins.size());
    auto iter1 = expected.additional_logins.begin();
    auto end1 = expected.additional_logins.end();
    auto iter2 = actual.additional_logins.begin();
    auto end2 = actual.additional_logins.end();
    for (; iter1 != end1 && iter2 != end2; ++iter1, ++iter2) {
      EXPECT_EQ(iter1->first, iter2->first);
      EXPECT_EQ(iter1->second.password, iter2->second.password);
      EXPECT_EQ(iter1->second.realm, iter2->second.realm);
    }
    ASSERT_EQ(iter1, end1);
    ASSERT_EQ(iter2, end2);
  }

  EXPECT_EQ(expected.wait_for_username, actual.wait_for_username);
}

void CheckEqualPasswordFormGenerationData(
    const PasswordFormGenerationData& expected,
    const PasswordFormGenerationData& actual) {
  EXPECT_EQ(expected.form_signature, actual.form_signature);
  EXPECT_EQ(expected.field_signature, actual.field_signature);
  ASSERT_EQ(expected.confirmation_field_signature.has_value(),
            actual.confirmation_field_signature.has_value());
  EXPECT_EQ(expected.confirmation_field_signature.value(),
            actual.confirmation_field_signature.value());
}

void CheckEqualPassPasswordGenerationUIData(
    const password_generation::PasswordGenerationUIData& expected,
    const password_generation::PasswordGenerationUIData& actual) {
  EXPECT_EQ(expected.bounds, actual.bounds);
  EXPECT_EQ(expected.max_length, actual.max_length);
  EXPECT_EQ(expected.generation_element, actual.generation_element);
  EXPECT_EQ(expected.text_direction, actual.text_direction);
  EXPECT_EQ(expected.password_form, actual.password_form);
}

}  // namespace

class AutofillTypeTraitsTestImpl : public testing::Test,
                                   public mojom::TypeTraitsTest {
 public:
  AutofillTypeTraitsTestImpl() {}

  mojom::TypeTraitsTestPtr GetTypeTraitsTestProxy() {
    mojom::TypeTraitsTestPtr proxy;
    bindings_.AddBinding(this, mojo::MakeRequest(&proxy));
    return proxy;
  }

  // mojom::TypeTraitsTest:
  void PassFormData(const FormData& s, PassFormDataCallback callback) override {
    std::move(callback).Run(s);
  }

  void PassFormFieldData(const FormFieldData& s,
                         PassFormFieldDataCallback callback) override {
    std::move(callback).Run(s);
  }

  void PassFormDataPredictions(
      const FormDataPredictions& s,
      PassFormDataPredictionsCallback callback) override {
    std::move(callback).Run(s);
  }

  void PassFormFieldDataPredictions(
      const FormFieldDataPredictions& s,
      PassFormFieldDataPredictionsCallback callback) override {
    std::move(callback).Run(s);
  }

  void PassPasswordFormFillData(
      const PasswordFormFillData& s,
      PassPasswordFormFillDataCallback callback) override {
    std::move(callback).Run(s);
  }

  void PassPasswordFormGenerationData(
      const PasswordFormGenerationData& s,
      PassPasswordFormGenerationDataCallback callback) override {
    std::move(callback).Run(s);
  }

  void PassPasswordGenerationUIData(
      const password_generation::PasswordGenerationUIData& s,
      PassPasswordGenerationUIDataCallback callback) override {
    std::move(callback).Run(s);
  }

  void PassPasswordForm(const PasswordForm& s,
                        PassPasswordFormCallback callback) override {
    std::move(callback).Run(s);
  }

  void PassFormsPredictionsMap(
      const FormsPredictionsMap& s,
      PassFormsPredictionsMapCallback callback) override {
    std::move(callback).Run(s);
  }

 private:
  base::MessageLoop loop_;

  mojo::BindingSet<TypeTraitsTest> bindings_;
};

void ExpectFormFieldData(const FormFieldData& expected,
                         const base::Closure& closure,
                         const FormFieldData& passed) {
  EXPECT_EQ(expected, passed);
  closure.Run();
}

void ExpectFormData(const FormData& expected,
                    const base::Closure& closure,
                    const FormData& passed) {
  EXPECT_EQ(expected, passed);
  closure.Run();
}

void ExpectFormFieldDataPredictions(const FormFieldDataPredictions& expected,
                                    const base::Closure& closure,
                                    const FormFieldDataPredictions& passed) {
  EXPECT_EQ(expected, passed);
  closure.Run();
}

void ExpectFormDataPredictions(const FormDataPredictions& expected,
                               const base::Closure& closure,
                               const FormDataPredictions& passed) {
  EXPECT_EQ(expected, passed);
  closure.Run();
}

void ExpectPasswordFormFillData(const PasswordFormFillData& expected,
                                const base::Closure& closure,
                                const PasswordFormFillData& passed) {
  CheckEqualPasswordFormFillData(expected, passed);
  closure.Run();
}

void ExpectPasswordFormGenerationData(
    const PasswordFormGenerationData& expected,
    const base::Closure& closure,
    const PasswordFormGenerationData& passed) {
  CheckEqualPasswordFormGenerationData(expected, passed);
  closure.Run();
}

void ExpectPasswordGenerationUIData(
    const password_generation::PasswordGenerationUIData& expected,
    base::OnceClosure closure,
    const password_generation::PasswordGenerationUIData& passed) {
  CheckEqualPassPasswordGenerationUIData(expected, passed);
  std::move(closure).Run();
}

void ExpectPasswordForm(const PasswordForm& expected,
                        const base::Closure& closure,
                        const PasswordForm& passed) {
  EXPECT_EQ(expected, passed);
  closure.Run();
}

void ExpectFormsPredictionsMap(const FormsPredictionsMap& expected,
                               const base::Closure& closure,
                               const FormsPredictionsMap& passed) {
  EXPECT_EQ(expected, passed);
  closure.Run();
}

TEST_F(AutofillTypeTraitsTestImpl, PassFormFieldData) {
  FormFieldData input;
  test::CreateTestSelectField("TestLabel", "TestName", "TestValue", kOptions,
                              kOptions, 4, &input);
  // Set other attributes to check if they are passed correctly.
  input.id_attribute = base::ASCIIToUTF16("id");
  input.name_attribute = base::ASCIIToUTF16("name");
  input.autocomplete_attribute = "on";
  input.placeholder = base::ASCIIToUTF16("placeholder");
  input.css_classes = base::ASCIIToUTF16("class1");
  input.aria_label = base::ASCIIToUTF16("aria label");
  input.aria_description = base::ASCIIToUTF16("aria description");
  input.max_length = 12345;
  input.is_autofilled = true;
  input.check_status = FormFieldData::CHECKED;
  input.should_autocomplete = true;
  input.role = FormFieldData::ROLE_ATTRIBUTE_PRESENTATION;
  input.text_direction = base::i18n::RIGHT_TO_LEFT;
  input.properties_mask = FieldPropertiesFlags::HAD_FOCUS;

  base::RunLoop loop;
  mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
  proxy->PassFormFieldData(
      input, base::Bind(&ExpectFormFieldData, input, loop.QuitClosure()));
  loop.Run();
}

TEST_F(AutofillTypeTraitsTestImpl, PassFormData) {
  FormData input;
  test::CreateTestAddressFormData(&input);
  input.username_predictions = {1, 13, 2};

  base::RunLoop loop;
  mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
  proxy->PassFormData(input,
                      base::Bind(&ExpectFormData, input, loop.QuitClosure()));
  loop.Run();
}

TEST_F(AutofillTypeTraitsTestImpl, PassFormFieldDataPredictions) {
  FormFieldDataPredictions input;
  CreateTestFieldDataPredictions("TestSignature", &input);

  base::RunLoop loop;
  mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
  proxy->PassFormFieldDataPredictions(
      input,
      base::Bind(&ExpectFormFieldDataPredictions, input, loop.QuitClosure()));
  loop.Run();
}

TEST_F(AutofillTypeTraitsTestImpl, PassFormDataPredictions) {
  FormDataPredictions input;
  test::CreateTestAddressFormData(&input.data);
  input.signature = "TestSignature";

  FormFieldDataPredictions field_predict;
  CreateTestFieldDataPredictions("Tom", &field_predict);
  input.fields.push_back(field_predict);
  CreateTestFieldDataPredictions("Jerry", &field_predict);
  input.fields.push_back(field_predict);
  CreateTestFieldDataPredictions("NoOne", &field_predict);
  input.fields.push_back(field_predict);

  base::RunLoop loop;
  mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
  proxy->PassFormDataPredictions(
      input, base::Bind(&ExpectFormDataPredictions, input, loop.QuitClosure()));
  loop.Run();
}

TEST_F(AutofillTypeTraitsTestImpl, PassPasswordFormFillData) {
  PasswordFormFillData input;
  CreateTestPasswordFormFillData(&input);

  base::RunLoop loop;
  mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
  proxy->PassPasswordFormFillData(input, base::Bind(&ExpectPasswordFormFillData,
                                                    input, loop.QuitClosure()));
  loop.Run();
}

TEST_F(AutofillTypeTraitsTestImpl, PassPasswordFormGenerationData) {
  FormData form;
  test::CreateTestAddressFormData(&form);
  FormSignature form_signature = CalculateFormSignature(form);
  FieldSignature field_signature =
      CalculateFieldSignatureForField(form.fields[0]);
  FieldSignature confirmation_field_signature =
      CalculateFieldSignatureForField(form.fields[1]);
  PasswordFormGenerationData input(form_signature, field_signature);
  input.confirmation_field_signature.emplace(confirmation_field_signature);

  base::RunLoop loop;
  mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
  proxy->PassPasswordFormGenerationData(
      input,
      base::Bind(&ExpectPasswordFormGenerationData, input, loop.QuitClosure()));
  loop.Run();
}

TEST_F(AutofillTypeTraitsTestImpl, PassPasswordGenerationUIData) {
  password_generation::PasswordGenerationUIData input;
  CreatePasswordGenerationUIData(&input);

  base::RunLoop loop;
  mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
  proxy->PassPasswordGenerationUIData(
      input, base::BindOnce(&ExpectPasswordGenerationUIData, input,
                            loop.QuitClosure()));
  loop.Run();
}

TEST_F(AutofillTypeTraitsTestImpl, PassPasswordForm) {
  PasswordForm input;
  CreateTestPasswordForm(&input);

  base::RunLoop loop;
  mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
  proxy->PassPasswordForm(
      input, base::Bind(&ExpectPasswordForm, input, loop.QuitClosure()));
  loop.Run();
}

TEST_F(AutofillTypeTraitsTestImpl, PassFormsPredictionsMap) {
  FormsPredictionsMap input;
  CreateTestFormsPredictionsMap(&input);

  base::RunLoop loop;
  mojom::TypeTraitsTestPtr proxy = GetTypeTraitsTestProxy();
  proxy->PassFormsPredictionsMap(
      input, base::Bind(&ExpectFormsPredictionsMap, input, loop.QuitClosure()));
  loop.Run();
}

}  // namespace autofill
