// 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/autofill/save_card_bubble_controller_impl.h"

#include <stddef.h>

#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/account_tracker_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/ssl/security_state_tab_helper.h"
#include "chrome/browser/ui/autofill/popup_constants.h"
#include "chrome/browser/ui/autofill/save_card_bubble_view.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/location_bar/location_bar.h"
#include "components/autofill/core/browser/autofill_experiments.h"
#include "components/autofill/core/browser/autofill_metrics.h"
#include "components/autofill/core/common/autofill_pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/signin_manager_base.h"
#include "components/strings/grit/components_strings.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/navigation_handle.h"
#include "ui/base/l10n/l10n_util.h"

DEFINE_WEB_CONTENTS_USER_DATA_KEY(autofill::SaveCardBubbleControllerImpl);

namespace autofill {

SaveCardBubbleControllerImpl::SaveCardBubbleControllerImpl(
    content::WebContents* web_contents)
    : content::WebContentsObserver(web_contents),
      web_contents_(web_contents),
      save_card_bubble_view_(nullptr),
      pref_service_(
          user_prefs::UserPrefs::Get(web_contents->GetBrowserContext())) {
  security_state::SecurityInfo security_info;
  SecurityStateTabHelper::FromWebContents(web_contents)
      ->GetSecurityInfo(&security_info);
  security_level_ = security_info.security_level;
}

SaveCardBubbleControllerImpl::~SaveCardBubbleControllerImpl() {
  if (save_card_bubble_view_)
    save_card_bubble_view_->Hide();
}

void SaveCardBubbleControllerImpl::ShowBubbleForLocalSave(
    const CreditCard& card,
    const base::Closure& save_card_callback) {
  // Don't show the bubble if it's already visible.
  if (save_card_bubble_view_)
    return;

  is_uploading_ = false;
  is_reshow_ = false;
  should_request_name_from_user_ = false;
  legal_message_lines_.clear();

  AutofillMetrics::LogSaveCardPromptMetric(
      AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, is_uploading_,
      is_reshow_, should_request_name_from_user_,
      pref_service_->GetInteger(
          prefs::kAutofillAcceptSaveCreditCardPromptState),
      GetSecurityLevel());

  card_ = card;
  local_save_card_callback_ = save_card_callback;
  ShowBubble();
}

void SaveCardBubbleControllerImpl::ShowBubbleForUpload(
    const CreditCard& card,
    std::unique_ptr<base::DictionaryValue> legal_message,
    bool should_request_name_from_user,
    base::OnceCallback<void(const base::string16&)> save_card_callback) {
  // Don't show the bubble if it's already visible.
  if (save_card_bubble_view_)
    return;

  // Fetch the logged-in user's AccountInfo if it has not yet been done.
  if (should_request_name_from_user && account_info_.IsEmpty())
    FetchAccountInfo();

  is_uploading_ = true;
  is_reshow_ = false;
  should_request_name_from_user_ = should_request_name_from_user;
  AutofillMetrics::LogSaveCardPromptMetric(
      AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, is_uploading_,
      is_reshow_, should_request_name_from_user_,
      pref_service_->GetInteger(
          prefs::kAutofillAcceptSaveCreditCardPromptState),
      GetSecurityLevel());

  if (!LegalMessageLine::Parse(*legal_message, &legal_message_lines_,
                               /*escape_apostrophes=*/true)) {
    AutofillMetrics::LogSaveCardPromptMetric(
        AutofillMetrics::SAVE_CARD_PROMPT_END_INVALID_LEGAL_MESSAGE,
        is_uploading_, is_reshow_, should_request_name_from_user_,
        pref_service_->GetInteger(
            prefs::kAutofillAcceptSaveCreditCardPromptState),
        GetSecurityLevel());
    return;
  }

  card_ = card;
  upload_save_card_callback_ = std::move(save_card_callback);
  ShowBubble();
}

void SaveCardBubbleControllerImpl::HideBubble() {
  if (save_card_bubble_view_) {
    save_card_bubble_view_->Hide();
    save_card_bubble_view_ = nullptr;
  }
}

void SaveCardBubbleControllerImpl::ReshowBubble() {
  // Don't show the bubble if it's already visible.
  if (save_card_bubble_view_)
    return;

  is_reshow_ = true;
  AutofillMetrics::LogSaveCardPromptMetric(
      AutofillMetrics::SAVE_CARD_PROMPT_SHOW_REQUESTED, is_uploading_,
      is_reshow_, should_request_name_from_user_,
      pref_service_->GetInteger(
          prefs::kAutofillAcceptSaveCreditCardPromptState),
      GetSecurityLevel());

  ShowBubble();
}

bool SaveCardBubbleControllerImpl::IsIconVisible() const {
  return !upload_save_card_callback_.is_null() ||
         !local_save_card_callback_.is_null();
}

SaveCardBubbleView* SaveCardBubbleControllerImpl::save_card_bubble_view()
    const {
  return save_card_bubble_view_;
}

base::string16 SaveCardBubbleControllerImpl::GetWindowTitle() const {
  return l10n_util::GetStringUTF16(
      IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_TO_CLOUD_V3);
}

base::string16 SaveCardBubbleControllerImpl::GetExplanatoryMessage() const {
  if (is_uploading_) {
    if (should_request_name_from_user_) {
      return l10n_util::GetStringUTF16(
          IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION_V3_WITH_NAME);
    }
    return l10n_util::GetStringUTF16(
        IsAutofillUpstreamUpdatePromptExplanationExperimentEnabled()
            ? IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION_V3
            : IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION_V2);
  }
  return base::string16();
}

const AccountInfo& SaveCardBubbleControllerImpl::GetAccountInfo() const {
  return account_info_;
}

const CreditCard& SaveCardBubbleControllerImpl::GetCard() const {
  return card_;
}

bool SaveCardBubbleControllerImpl::ShouldRequestNameFromUser() const {
  return should_request_name_from_user_;
}

void SaveCardBubbleControllerImpl::OnSaveButton(
    const base::string16& cardholder_name) {
  if (!upload_save_card_callback_.is_null()) {
    base::string16 name_provided_by_user;
    if (!cardholder_name.empty()) {
      // Trim the cardholder name provided by the user and send it in the
      // callback so it can be included in the final request.
      DCHECK(ShouldRequestNameFromUser());
      base::TrimWhitespace(cardholder_name, base::TRIM_ALL,
                           &name_provided_by_user);
    }
    std::move(upload_save_card_callback_).Run(name_provided_by_user);
  } else {
    DCHECK(!local_save_card_callback_.is_null());
    local_save_card_callback_.Run();
    local_save_card_callback_.Reset();
  }
  AutofillMetrics::LogSaveCardPromptMetric(
      AutofillMetrics::SAVE_CARD_PROMPT_END_ACCEPTED, is_uploading_, is_reshow_,
      should_request_name_from_user_,
      pref_service_->GetInteger(
          prefs::kAutofillAcceptSaveCreditCardPromptState),
      GetSecurityLevel());
  pref_service_->SetInteger(
      prefs::kAutofillAcceptSaveCreditCardPromptState,
      prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_ACCEPTED);
}

void SaveCardBubbleControllerImpl::OnCancelButton() {
  upload_save_card_callback_.Reset();
  local_save_card_callback_.Reset();
  AutofillMetrics::LogSaveCardPromptMetric(
      AutofillMetrics::SAVE_CARD_PROMPT_END_DENIED, is_uploading_, is_reshow_,
      should_request_name_from_user_,
      pref_service_->GetInteger(
          prefs::kAutofillAcceptSaveCreditCardPromptState),
      GetSecurityLevel());
  pref_service_->SetInteger(
      prefs::kAutofillAcceptSaveCreditCardPromptState,
      prefs::PREVIOUS_SAVE_CREDIT_CARD_PROMPT_USER_DECISION_DENIED);
}

void SaveCardBubbleControllerImpl::OnLegalMessageLinkClicked(const GURL& url) {
  OpenUrl(url);
  AutofillMetrics::LogSaveCardPromptMetric(
      AutofillMetrics::SAVE_CARD_PROMPT_DISMISS_CLICK_LEGAL_MESSAGE,
      is_uploading_, is_reshow_, should_request_name_from_user_,
      pref_service_->GetInteger(
          prefs::kAutofillAcceptSaveCreditCardPromptState),
      GetSecurityLevel());
}

void SaveCardBubbleControllerImpl::OnBubbleClosed() {
  save_card_bubble_view_ = nullptr;
  UpdateIcon();
}

const LegalMessageLines& SaveCardBubbleControllerImpl::GetLegalMessageLines()
    const {
  return legal_message_lines_;
}

base::TimeDelta SaveCardBubbleControllerImpl::Elapsed() const {
  return timer_->Elapsed();
}

void SaveCardBubbleControllerImpl::DidFinishNavigation(
    content::NavigationHandle* navigation_handle) {
  if (!navigation_handle->IsInMainFrame() || !navigation_handle->HasCommitted())
    return;

  // Nothing to do if there's no bubble available.
  if (upload_save_card_callback_.is_null() &&
      local_save_card_callback_.is_null()) {
    return;
  }

  // Don't react to same-document (fragment) navigations.
  if (navigation_handle->IsSameDocument())
    return;

  // Don't do anything if a navigation occurs before a user could reasonably
  // interact with the bubble.
  if (Elapsed() < kCardBubbleSurviveNavigationTime)
    return;

  // Otherwise, get rid of the bubble and icon.
  upload_save_card_callback_.Reset();
  local_save_card_callback_.Reset();
  bool bubble_was_visible = save_card_bubble_view_;
  if (bubble_was_visible) {
    save_card_bubble_view_->Hide();
    OnBubbleClosed();
  } else {
    UpdateIcon();
  }
  AutofillMetrics::LogSaveCardPromptMetric(
      bubble_was_visible
          ? AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_SHOWING
          : AutofillMetrics::SAVE_CARD_PROMPT_END_NAVIGATION_HIDDEN,
      is_uploading_, is_reshow_, should_request_name_from_user_,
      pref_service_->GetInteger(
          prefs::kAutofillAcceptSaveCreditCardPromptState),
      GetSecurityLevel());
}

void SaveCardBubbleControllerImpl::OnVisibilityChanged(
    content::Visibility visibility) {
  if (visibility == content::Visibility::HIDDEN)
    HideBubble();
}

void SaveCardBubbleControllerImpl::WebContentsDestroyed() {
  HideBubble();
}

void SaveCardBubbleControllerImpl::FetchAccountInfo() {
  Profile* profile =
      Profile::FromBrowserContext(web_contents_->GetBrowserContext());
  if (!profile)
    return;
  SigninManagerBase* signin_manager =
      SigninManagerFactory::GetForProfile(profile);
  AccountTrackerService* account_tracker =
      AccountTrackerServiceFactory::GetForProfile(profile);
  if (!signin_manager || !account_tracker)
    return;
  account_info_ = account_tracker->GetAccountInfo(
      signin_manager->GetAuthenticatedAccountId());
}

void SaveCardBubbleControllerImpl::ShowBubble() {
  DCHECK(!upload_save_card_callback_.is_null() ||
         !local_save_card_callback_.is_null());
  DCHECK(!save_card_bubble_view_);

  // Need to create location bar icon before bubble, otherwise bubble will be
  // unanchored.
  UpdateIcon();

  Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
  save_card_bubble_view_ = browser->window()->ShowSaveCreditCardBubble(
      web_contents(), this, is_reshow_);
  DCHECK(save_card_bubble_view_);

  // Update icon after creating |save_card_bubble_view_| so that icon will show
  // its "toggled on" state.
  UpdateIcon();

  timer_.reset(new base::ElapsedTimer());

  AutofillMetrics::LogSaveCardPromptMetric(
      AutofillMetrics::SAVE_CARD_PROMPT_SHOWN, is_uploading_, is_reshow_,
      should_request_name_from_user_,
      pref_service_->GetInteger(
          prefs::kAutofillAcceptSaveCreditCardPromptState),
      GetSecurityLevel());
}

void SaveCardBubbleControllerImpl::UpdateIcon() {
  Browser* browser = chrome::FindBrowserWithWebContents(web_contents());
  if (!browser)
    return;
  LocationBar* location_bar = browser->window()->GetLocationBar();
  location_bar->UpdateSaveCreditCardIcon();
}

void SaveCardBubbleControllerImpl::OpenUrl(const GURL& url) {
  web_contents()->OpenURL(content::OpenURLParams(
      url, content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui::PAGE_TRANSITION_LINK, false));
}

security_state::SecurityLevel SaveCardBubbleControllerImpl::GetSecurityLevel()
    const {
  return security_level_;
}

}  // namespace autofill
