// 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 "components/payments/content/payment_request_state.h"

#include <algorithm>
#include <set>
#include <utility>

#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/payments/content/payment_request_spec.h"
#include "components/payments/content/payment_response_helper.h"
#include "components/payments/core/autofill_payment_instrument.h"
#include "components/payments/core/payment_instrument.h"
#include "components/payments/core/payment_request_delegate.h"
#include "components/payments/core/profile_util.h"

namespace payments {

PaymentRequestState::PaymentRequestState(
    PaymentRequestSpec* spec,
    Delegate* delegate,
    const std::string& app_locale,
    autofill::PersonalDataManager* personal_data_manager,
    PaymentRequestDelegate* payment_request_delegate)
    : is_ready_to_pay_(false),
      app_locale_(app_locale),
      spec_(spec),
      delegate_(delegate),
      personal_data_manager_(personal_data_manager),
      selected_shipping_profile_(nullptr),
      selected_contact_profile_(nullptr),
      selected_instrument_(nullptr),
      payment_request_delegate_(payment_request_delegate) {
  PopulateProfileCache();
  SetDefaultProfileSelections();
}
PaymentRequestState::~PaymentRequestState() {}

void PaymentRequestState::OnPaymentResponseReady(
    mojom::PaymentResponsePtr payment_response) {
  delegate_->OnPaymentResponseAvailable(std::move(payment_response));
}

bool PaymentRequestState::CanMakePayment() const {
  for (const std::unique_ptr<PaymentInstrument>& instrument :
       available_instruments_) {
    if (instrument->IsValidForCanMakePayment()) {
      // AddAutofillPaymentInstrument() filters out available instruments based
      // on supported card networks.
      DCHECK(spec_->supported_card_networks_set().find(
                 instrument->method_name()) !=
             spec_->supported_card_networks_set().end());
      return true;
    }
  }
  return false;
}

bool PaymentRequestState::AreRequestedMethodsSupported() const {
  return !spec_->supported_card_networks().empty();
}

void PaymentRequestState::AddObserver(Observer* observer) {
  CHECK(observer);
  observers_.AddObserver(observer);
}

void PaymentRequestState::RemoveObserver(Observer* observer) {
  observers_.RemoveObserver(observer);
}

void PaymentRequestState::GeneratePaymentResponse() {
  DCHECK(is_ready_to_pay());

  // Once the response is ready, will call back into OnPaymentResponseReady.
  response_helper_ = base::MakeUnique<PaymentResponseHelper>(
      app_locale_, spec_, selected_instrument_, payment_request_delegate_,
      selected_shipping_profile_, selected_contact_profile_, this);
}

void PaymentRequestState::AddAutofillPaymentInstrument(
    bool selected,
    const autofill::CreditCard& card) {
  std::string basic_card_network =
      autofill::data_util::GetPaymentRequestData(card.type())
          .basic_card_payment_type;
  if (!spec_->supported_card_networks_set().count(basic_card_network))
    return;

  // AutofillPaymentInstrument makes a copy of |card| so it is effectively
  // owned by this object.
  std::unique_ptr<PaymentInstrument> instrument =
      base::MakeUnique<AutofillPaymentInstrument>(
          basic_card_network, card, shipping_profiles_, app_locale_,
          payment_request_delegate_);
  available_instruments_.push_back(std::move(instrument));

  if (selected)
    SetSelectedInstrument(available_instruments_.back().get());
}

void PaymentRequestState::SetSelectedShippingOption(
    const std::string& shipping_option_id) {
  spec_->StartWaitingForUpdateWith(
      PaymentRequestSpec::UpdateReason::SHIPPING_OPTION);
  // This will inform the merchant and will lead to them calling updateWith with
  // new PaymentDetails.
  delegate_->OnShippingOptionIdSelected(shipping_option_id);
}

void PaymentRequestState::SetSelectedShippingProfile(
    autofill::AutofillProfile* profile) {
  spec_->StartWaitingForUpdateWith(
      PaymentRequestSpec::UpdateReason::SHIPPING_ADDRESS);
  selected_shipping_profile_ = profile;
  UpdateIsReadyToPayAndNotifyObservers();
  delegate_->OnShippingAddressSelected(
      PaymentResponseHelper::GetMojomPaymentAddressFromAutofillProfile(
          selected_shipping_profile_, app_locale_));
}

void PaymentRequestState::SetSelectedContactProfile(
    autofill::AutofillProfile* profile) {
  selected_contact_profile_ = profile;
  UpdateIsReadyToPayAndNotifyObservers();
}

void PaymentRequestState::SetSelectedInstrument(PaymentInstrument* instrument) {
  selected_instrument_ = instrument;
  UpdateIsReadyToPayAndNotifyObservers();
}

const std::string& PaymentRequestState::GetApplicationLocale() {
  return app_locale_;
}

autofill::PersonalDataManager* PaymentRequestState::GetPersonalDataManager() {
  return personal_data_manager_;
}

std::unique_ptr<const ::i18n::addressinput::Source>
PaymentRequestState::GetAddressInputSource() {
  return payment_request_delegate_->GetAddressInputSource();
}

std::unique_ptr<::i18n::addressinput::Storage>
PaymentRequestState::GetAddressInputStorage() {
  return payment_request_delegate_->GetAddressInputStorage();
}

void PaymentRequestState::PopulateProfileCache() {
  std::vector<autofill::AutofillProfile*> profiles =
      personal_data_manager_->GetProfilesToSuggest();

  // PaymentRequest may outlive the Profiles returned by the Data Manager.
  // Thus, we store copies, and return a vector of pointers to these copies
  // whenever Profiles are requested. The same is true for credit cards.
  for (size_t i = 0; i < profiles.size(); i++) {
    profile_cache_.push_back(
        base::MakeUnique<autofill::AutofillProfile>(*profiles[i]));

    // TODO(tmartino): Implement deduplication rules specific to shipping
    // profiles.
    shipping_profiles_.push_back(profile_cache_[i].get());
  }

  std::vector<autofill::AutofillProfile*> raw_profiles_for_filtering(
      profile_cache_.size());
  std::transform(profile_cache_.begin(), profile_cache_.end(),
                 raw_profiles_for_filtering.begin(),
                 [](const std::unique_ptr<autofill::AutofillProfile>& p) {
                   return p.get();
                 });

  contact_profiles_ = profile_util::FilterProfilesForContact(
      raw_profiles_for_filtering, GetApplicationLocale(), *spec_);

  // Create the list of available instruments.
  const std::vector<autofill::CreditCard*>& cards =
      personal_data_manager_->GetCreditCardsToSuggest();
  for (autofill::CreditCard* card : cards)
    AddAutofillPaymentInstrument(/*selected=*/false, *card);
}

void PaymentRequestState::SetDefaultProfileSelections() {
  // Only pre-select an address if the merchant provided at least one selected
  // shipping option.
  if (!shipping_profiles().empty() && spec_->selected_shipping_option())
    selected_shipping_profile_ = shipping_profiles()[0];

  if (!contact_profiles().empty())
    selected_contact_profile_ = contact_profiles()[0];

  // TODO(crbug.com/702063): Change this code to prioritize instruments by use
  // count and other means, and implement a way to modify this function's return
  // value.
  const std::vector<std::unique_ptr<PaymentInstrument>>& instruments =
      available_instruments();
  auto first_complete_instrument =
      std::find_if(instruments.begin(), instruments.end(),
                   [](const std::unique_ptr<PaymentInstrument>& instrument) {
                     return instrument->IsCompleteForPayment();
                   });

  selected_instrument_ = first_complete_instrument == instruments.end()
                             ? nullptr
                             : first_complete_instrument->get();

  UpdateIsReadyToPayAndNotifyObservers();
}

void PaymentRequestState::UpdateIsReadyToPayAndNotifyObservers() {
  is_ready_to_pay_ =
      ArePaymentDetailsSatisfied() && ArePaymentOptionsSatisfied();
  NotifyOnSelectedInformationChanged();
}

void PaymentRequestState::NotifyOnSelectedInformationChanged() {
  for (auto& observer : observers_)
    observer.OnSelectedInformationChanged();
}

bool PaymentRequestState::ArePaymentDetailsSatisfied() {
  // There is no need to check for supported networks, because only supported
  // instruments are listed/created in the flow.
  return selected_instrument_ != nullptr &&
         selected_instrument_->IsCompleteForPayment();
}

bool PaymentRequestState::ArePaymentOptionsSatisfied() {
  // TODO(mathp): Have a measure of shipping address completeness.
  if (spec_->request_shipping() && selected_shipping_profile_ == nullptr)
    return false;

  profile_util::PaymentsProfileComparator comparator(app_locale_, *spec_);
  return comparator.IsContactInfoComplete(selected_contact_profile_);
}

}  // namespace payments
