// 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/ui/passwords/manage_passwords_state.h"

#include <algorithm>
#include <utility>

#include "components/password_manager/core/browser/browser_save_password_progress_logger.h"
#include "components/password_manager/core/browser/log_manager.h"
#include "components/password_manager/core/browser/password_form_manager_for_ui.h"
#include "components/password_manager/core/browser/password_manager.h"
#include "components/password_manager/core/browser/password_manager_client.h"

using password_manager::PasswordFormManagerForUI;

namespace {

std::vector<std::unique_ptr<autofill::PasswordForm>> DeepCopyNonPSLMapToVector(
    const std::map<base::string16, const autofill::PasswordForm*>&
        password_form_map) {
  std::vector<std::unique_ptr<autofill::PasswordForm>> result;
  result.reserve(password_form_map.size());
  for (const auto& form_pair : password_form_map) {
    if (!form_pair.second->is_public_suffix_match) {
      result.push_back(
          std::make_unique<autofill::PasswordForm>(*form_pair.second));
    }
  }
  return result;
}

void AppendDeepCopyVector(
    const std::vector<const autofill::PasswordForm*>& forms,
    std::vector<std::unique_ptr<autofill::PasswordForm>>* result) {
  result->reserve(result->size() + forms.size());
  for (auto* form : forms)
    result->push_back(std::make_unique<autofill::PasswordForm>(*form));
}

// Updates one form in |forms| that has the same unique key as |updated_form|.
// Returns true if the form was found and updated.
bool UpdateFormInVector(
    const autofill::PasswordForm& updated_form,
    std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) {
  auto it = std::find_if(
      forms->begin(), forms->end(),
      [&updated_form](const std::unique_ptr<autofill::PasswordForm>& form) {
        return ArePasswordFormUniqueKeyEqual(*form, updated_form);
      });
  if (it != forms->end()) {
    **it = updated_form;
    return true;
  }
  return false;
}

// Removes a form from |forms| that has the same unique key as |form_to_delete|.
// Returns true iff the form was deleted.
bool RemoveFormFromVector(
    const autofill::PasswordForm& form_to_delete,
    std::vector<std::unique_ptr<autofill::PasswordForm>>* forms) {
  auto it = std::find_if(
      forms->begin(), forms->end(),
      [&form_to_delete](const std::unique_ptr<autofill::PasswordForm>& form) {
        return ArePasswordFormUniqueKeyEqual(*form, form_to_delete);
      });
  if (it != forms->end()) {
    forms->erase(it);
    return true;
  }
  return false;
}

}  // namespace

ManagePasswordsState::ManagePasswordsState()
    : state_(password_manager::ui::INACTIVE_STATE),
      client_(nullptr) {
}

ManagePasswordsState::~ManagePasswordsState() {}

void ManagePasswordsState::OnPendingPassword(
    std::unique_ptr<PasswordFormManagerForUI> form_manager) {
  ClearData();
  form_manager_ = std::move(form_manager);
  local_credentials_forms_ =
      DeepCopyNonPSLMapToVector(form_manager_->GetBestMatches());
  AppendDeepCopyVector(form_manager_->GetFormFetcher()->GetFederatedMatches(),
                       &local_credentials_forms_);
  origin_ = form_manager_->GetOrigin();
  SetState(password_manager::ui::PENDING_PASSWORD_STATE);
}

void ManagePasswordsState::OnUpdatePassword(
    std::unique_ptr<password_manager::PasswordFormManagerForUI> form_manager) {
  ClearData();
  form_manager_ = std::move(form_manager);
  local_credentials_forms_ =
      DeepCopyNonPSLMapToVector(form_manager_->GetBestMatches());
  AppendDeepCopyVector(form_manager_->GetFormFetcher()->GetFederatedMatches(),
                       &local_credentials_forms_);
  origin_ = form_manager_->GetOrigin();
  SetState(password_manager::ui::PENDING_PASSWORD_UPDATE_STATE);
}

void ManagePasswordsState::OnRequestCredentials(
    std::vector<std::unique_ptr<autofill::PasswordForm>> local_credentials,
    const GURL& origin) {
  ClearData();
  local_credentials_forms_ = std::move(local_credentials);
  origin_ = origin;
  SetState(password_manager::ui::CREDENTIAL_REQUEST_STATE);
}

void ManagePasswordsState::OnAutoSignin(
    std::vector<std::unique_ptr<autofill::PasswordForm>> local_forms,
    const GURL& origin) {
  DCHECK(!local_forms.empty());
  ClearData();
  local_credentials_forms_ = std::move(local_forms);
  origin_ = origin;
  SetState(password_manager::ui::AUTO_SIGNIN_STATE);
}

void ManagePasswordsState::OnAutomaticPasswordSave(
    std::unique_ptr<PasswordFormManagerForUI> form_manager) {
  ClearData();
  form_manager_ = std::move(form_manager);
  local_credentials_forms_.reserve(form_manager_->GetBestMatches().size());
  for (const auto& form : form_manager_->GetBestMatches()) {
    if (form.second->is_public_suffix_match)
      continue;
    local_credentials_forms_.push_back(
        std::make_unique<autofill::PasswordForm>(*form.second));
  }
  AppendDeepCopyVector(form_manager_->GetFormFetcher()->GetFederatedMatches(),
                       &local_credentials_forms_);
  origin_ = form_manager_->GetOrigin();
  SetState(password_manager::ui::CONFIRMATION_STATE);
}

void ManagePasswordsState::OnPasswordAutofilled(
    const std::map<base::string16, const autofill::PasswordForm*>&
        password_form_map,
    const GURL& origin,
    const std::vector<const autofill::PasswordForm*>* federated_matches) {
  DCHECK(!password_form_map.empty());
  ClearData();
  local_credentials_forms_ = DeepCopyNonPSLMapToVector(password_form_map);
  if (federated_matches)
    AppendDeepCopyVector(*federated_matches, &local_credentials_forms_);

  if (local_credentials_forms_.empty()) {
    // Don't show the UI for PSL matched passwords. They are not stored for this
    // page and cannot be deleted.
    origin_ = GURL();
    SetState(password_manager::ui::INACTIVE_STATE);
  } else {
    origin_ = origin;
    SetState(password_manager::ui::MANAGE_STATE);
  }
}

void ManagePasswordsState::OnInactive() {
  ClearData();
  origin_ = GURL();
  SetState(password_manager::ui::INACTIVE_STATE);
}

void ManagePasswordsState::TransitionToState(
    password_manager::ui::State state) {
  DCHECK_NE(password_manager::ui::INACTIVE_STATE, state_);
  DCHECK_EQ(password_manager::ui::MANAGE_STATE, state);
  if (state_ == password_manager::ui::CREDENTIAL_REQUEST_STATE) {
    if (!credentials_callback_.is_null()) {
      credentials_callback_.Run(nullptr);
      credentials_callback_.Reset();
    }
  }
  SetState(state);
}

void ManagePasswordsState::ProcessLoginsChanged(
    const password_manager::PasswordStoreChangeList& changes) {
  if (state() == password_manager::ui::INACTIVE_STATE)
    return;

  bool applied_delete = false;
  bool all_changes_are_deletion = true;
  for (const password_manager::PasswordStoreChange& change : changes) {
    if (change.type() != password_manager::PasswordStoreChange::REMOVE)
      all_changes_are_deletion = false;
    const autofill::PasswordForm& changed_form = change.form();
    if (changed_form.blacklisted_by_user)
      continue;
    if (change.type() == password_manager::PasswordStoreChange::REMOVE) {
      if (RemoveFormFromVector(changed_form, &local_credentials_forms_))
        applied_delete = true;
    } else if (change.type() == password_manager::PasswordStoreChange::UPDATE) {
      UpdateFormInVector(changed_form, &local_credentials_forms_);
    } else {
      DCHECK_EQ(password_manager::PasswordStoreChange::ADD, change.type());
      AddForm(changed_form);
    }
  }
  // Let the password manager know that it should update the list of the
  // credentials. We react only to deletion because in case the password manager
  // itself adds a credential, they should not be refetched. The password
  // generation can be confused as the generated password will be refetched and
  // autofilled immediately.
  if (applied_delete && all_changes_are_deletion)
    client_->UpdateFormManagers();
}

void ManagePasswordsState::ChooseCredential(
    const autofill::PasswordForm* form) {
  DCHECK_EQ(password_manager::ui::CREDENTIAL_REQUEST_STATE, state());
  DCHECK(!credentials_callback().is_null());

  credentials_callback().Run(form);
  set_credentials_callback(ManagePasswordsState::CredentialsCallback());
}

void ManagePasswordsState::ClearData() {
  form_manager_.reset();
  local_credentials_forms_.clear();
  credentials_callback_.Reset();
}

bool ManagePasswordsState::AddForm(const autofill::PasswordForm& form) {
  if (form.origin.GetOrigin() != origin_.GetOrigin())
    return false;
  if (UpdateFormInVector(form, &local_credentials_forms_))
    return true;
  local_credentials_forms_.push_back(
      std::make_unique<autofill::PasswordForm>(form));
  return true;
}

void ManagePasswordsState::SetState(password_manager::ui::State state) {
  DCHECK(client_);
  if (client_->GetLogManager()->IsLoggingActive()) {
    password_manager::BrowserSavePasswordProgressLogger logger(
        client_->GetLogManager());
    logger.LogNumber(
        autofill::SavePasswordProgressLogger::STRING_NEW_UI_STATE,
        state);
  }
  state_ = state;
}
