// Copyright 2018 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.

#import "ios/chrome/browser/passwords/password_controller.h"

#include <stddef.h>

#include <algorithm>
#include <map>
#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/mac/foundation_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string16.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "base/values.h"
#include "components/autofill/core/browser/ui/popup_item_ids.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/password_form.h"
#include "components/autofill/core/common/password_form_fill_data.h"
#include "components/autofill/core/common/password_form_generation_data.h"
#include "components/autofill/ios/browser/autofill_util.h"
#import "components/autofill/ios/form_util/form_activity_observer_bridge.h"
#include "components/infobars/core/infobar_manager.h"
#include "components/password_manager/core/browser/password_bubble_experiment.h"
#include "components/password_manager/core/browser/password_generation_frame_helper.h"
#include "components/password_manager/core/browser/password_manager.h"
#include "components/password_manager/core/browser/password_manager_client.h"
#include "components/password_manager/core/browser/password_manager_driver.h"
#include "components/password_manager/ios/account_select_fill_data.h"
#import "components/password_manager/ios/js_password_manager.h"
#import "components/password_manager/ios/password_suggestion_helper.h"
#include "components/strings/grit/components_strings.h"
#include "components/sync/driver/sync_service.h"
#import "components/ukm/ios/ukm_url_recorder.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/infobars/infobar_ios.h"
#include "ios/chrome/browser/infobars/infobar_manager_impl.h"
#import "ios/chrome/browser/infobars/infobar_type.h"
#include "ios/chrome/browser/passwords/credential_manager.h"
#import "ios/chrome/browser/passwords/ios_chrome_save_password_infobar_delegate.h"
#import "ios/chrome/browser/passwords/ios_chrome_update_password_infobar_delegate.h"
#import "ios/chrome/browser/passwords/ios_password_infobar_controller.h"
#import "ios/chrome/browser/passwords/notify_auto_signin_view_controller.h"
#import "ios/chrome/browser/passwords/password_form_filler.h"
#include "ios/chrome/browser/passwords/password_manager_features.h"
#include "ios/chrome/browser/sync/profile_sync_service_factory.h"
#import "ios/chrome/browser/ui/alert_coordinator/action_sheet_coordinator.h"
#import "ios/chrome/browser/ui/commands/application_commands.h"
#import "ios/chrome/browser/ui/commands/password_breach_commands.h"
#import "ios/chrome/browser/ui/infobars/coordinators/infobar_password_coordinator.h"
#import "ios/chrome/browser/ui/infobars/infobar_feature.h"
#include "ios/chrome/browser/ui/util/ui_util.h"
#include "ios/chrome/browser/web/tab_id_tab_helper.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/web/common/origin_util.h"
#include "ios/web/common/url_scheme_util.h"
#import "ios/web/public/deprecated/crw_js_injection_receiver.h"
#include "ios/web/public/js_messaging/web_frame.h"
#include "ios/web/public/js_messaging/web_frame_util.h"
#import "ios/web/public/web_state.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "ui/base/l10n/l10n_util_mac.h"
#include "url/gurl.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

using autofill::FormData;
using autofill::PasswordFormGenerationData;
using autofill::PasswordForm;
using base::SysNSStringToUTF16;
using base::SysUTF16ToNSString;
using l10n_util::GetNSString;
using l10n_util::GetNSStringF;
using password_manager::metrics_util::LogPasswordDropdownShown;
using password_manager::metrics_util::PasswordDropdownState;
using password_manager::AccountSelectFillData;
using password_manager::FillData;
using password_manager::GetPageURLAndCheckTrustLevel;
using password_manager::PasswordFormManagerForUI;
using password_manager::PasswordGenerationFrameHelper;
using password_manager::PasswordManager;
using password_manager::PasswordManagerClient;
using password_manager::PasswordManagerDriver;
using password_manager::SerializeFillData;
using password_manager::SerializePasswordFormFillData;

namespace {
// Types of password infobars to display.
enum class PasswordInfoBarType { SAVE, UPDATE };

// Password is considered not generated when user edits it below 4 characters.
constexpr int kMinimumLengthForEditedPassword = 4;

// Duration for notify user auto-sign in dialog being displayed.
constexpr int kNotifyAutoSigninDuration = 3;  // seconds

// The string ' •••' appended to the username in the suggestion.
NSString* const kSuggestionSuffix = @" ••••••••";
}  // namespace

@interface PasswordController ()<PasswordSuggestionHelperDelegate>

// View controller for auto sign-in notification, owned by this
// PasswordController.
@property(nonatomic, strong)
    NotifyUserAutoSigninViewController* notifyAutoSigninViewController;

// Helper contains common password form processing logic.
@property(nonatomic, readonly) PasswordFormHelper* formHelper;

// Helper contains common password suggestion logic.
@property(nonatomic, readonly) PasswordSuggestionHelper* suggestionHelper;

// The action sheet coordinator, if one is currently being shown.
@property(nonatomic, strong) ActionSheetCoordinator* actionSheetCoordinator;

// Tracks if current password is generated.
@property(nonatomic, assign) BOOL isPasswordGenerated;

// Tracks field when current password was generated.
@property(nonatomic, copy) NSString* passwordGeneratedIdentifier;

// Tracks current potential generated password until accepted or rejected.
@property(nonatomic, copy) NSString* generatedPotentialPassword;

@end

@interface PasswordController ()<FormSuggestionProvider, PasswordFormFiller>

// Informs the |_passwordManager| of the password forms (if any were present)
// that have been found on the page.
- (void)didFinishPasswordFormExtraction:
    (const std::vector<autofill::FormData>&)forms;

// Finds all password forms in DOM and sends them to the password store for
// fetching stored credentials.
- (void)findPasswordFormsAndSendThemToPasswordStore;

// Displays infobar for |form| with |type|. If |type| is UPDATE, the user
// is prompted to update the password. If |type| is SAVE, the user is prompted
// to save the password.
- (void)showInfoBarForForm:(std::unique_ptr<PasswordFormManagerForUI>)form
               infoBarType:(PasswordInfoBarType)type;

// Hides auto sign-in notification. Removes the view from superview and destroys
// the controller.
// TODO(crbug.com/435048): Animate disappearance.
- (void)hideAutosigninNotification;

@end

@implementation PasswordController {
  std::unique_ptr<PasswordManager> _passwordManager;
  std::unique_ptr<PasswordGenerationFrameHelper> _passwordGenerationHelper;
  std::unique_ptr<PasswordManagerClient> _passwordManagerClient;
  std::unique_ptr<PasswordManagerDriver> _passwordManagerDriver;
  std::unique_ptr<CredentialManager> _credentialManager;

  // The WebState this instance is observing. Will be null after
  // -webStateDestroyed: has been called.
  web::WebState* _webState;

  // Bridge to observe WebState from Objective-C.
  std::unique_ptr<web::WebStateObserverBridge> _webStateObserverBridge;

  // Timer for hiding "Signing in as ..." notification.
  base::OneShotTimer _notifyAutoSigninTimer;

  // User credential waiting to be displayed in autosign-in snackbar, once tab
  // becomes active.
  std::unique_ptr<autofill::PasswordForm> _pendingAutoSigninPasswordForm;

  // Form data for password generation on this page.
  std::map<base::string16, PasswordFormGenerationData> _formGenerationData;
}

- (instancetype)initWithWebState:(web::WebState*)webState {
  self = [self initWithWebState:webState client:nullptr];
  return self;
}

- (instancetype)initWithWebState:(web::WebState*)webState
                          client:(std::unique_ptr<PasswordManagerClient>)
                                     passwordManagerClient {
  self = [super init];
  if (self) {
    DCHECK(webState);
    _webState = webState;
    _webStateObserverBridge =
        std::make_unique<web::WebStateObserverBridge>(self);
    _webState->AddObserver(_webStateObserverBridge.get());
    _formHelper =
        [[PasswordFormHelper alloc] initWithWebState:webState delegate:self];
    _suggestionHelper =
        [[PasswordSuggestionHelper alloc] initWithDelegate:self];
    if (passwordManagerClient)
      _passwordManagerClient = std::move(passwordManagerClient);
    else
      _passwordManagerClient.reset(new IOSChromePasswordManagerClient(self));
    _passwordManager.reset(new PasswordManager(_passwordManagerClient.get()));
    _passwordManagerDriver.reset(new IOSChromePasswordManagerDriver(self));

    if (!_passwordManagerClient->IsIncognito()) {
      _passwordGenerationHelper.reset(new PasswordGenerationFrameHelper(
          _passwordManagerClient.get(), _passwordManagerDriver.get()));
    }

    if (base::FeatureList::IsEnabled(features::kCredentialManager)) {
      _credentialManager = std::make_unique<CredentialManager>(
          _passwordManagerClient.get(), _webState);
    }
  }
  return self;
}

- (void)dealloc {
  if (_webState) {
    _webState->RemoveObserver(_webStateObserverBridge.get());
  }
}

#pragma mark - Properties

- (id<PasswordFormFiller>)passwordFormFiller {
  return self;
}

- (ukm::SourceId)ukmSourceId {
  return _webState ? ukm::GetSourceIdForWebStateDocument(_webState)
                   : ukm::kInvalidSourceId;
}

- (PasswordManagerClient*)passwordManagerClient {
  return _passwordManagerClient.get();
}

- (PasswordManagerDriver*)passwordManagerDriver {
  return _passwordManagerDriver.get();
}

#pragma mark - PasswordFormFiller

- (void)findAndFillPasswordForms:(NSString*)username
                        password:(NSString*)password
               completionHandler:(void (^)(BOOL))completionHandler {
  [self.formHelper findAndFillPasswordFormsWithUserName:username
                                               password:password
                                      completionHandler:completionHandler];
}

#pragma mark - CRWWebStateObserver

// If Tab was shown, and there is a pending PasswordForm, display autosign-in
// notification.
- (void)webStateWasShown:(web::WebState*)webState {
  DCHECK_EQ(_webState, webState);
  if (_pendingAutoSigninPasswordForm) {
    [self showAutosigninNotification:std::move(_pendingAutoSigninPasswordForm)];
    _pendingAutoSigninPasswordForm.reset();
  }
}

// If Tab was hidden, hide auto sign-in notification.
- (void)webStateWasHidden:(web::WebState*)webState {
  DCHECK_EQ(_webState, webState);
  [self hideAutosigninNotification];
}

- (void)webState:(web::WebState*)webState didLoadPageWithSuccess:(BOOL)success {
  DCHECK_EQ(_webState, webState);
  // Clear per-page state.
  [self.suggestionHelper resetForNewPage];

  // Retrieve the identity of the page. In case the page might be malicous,
  // returns early.
  GURL pageURL;
  if (!GetPageURLAndCheckTrustLevel(webState, &pageURL))
    return;

  if (!web::UrlHasWebScheme(pageURL))
    return;

  // Notify the password manager that the page loaded so it can clear its own
  // per-page state.
  self.passwordManager->DidNavigateMainFrame(/*form_may_be_submitted=*/true);

  if (!webState->ContentIsHTML()) {
    // If the current page is not HTML, it does not contain any HTML forms.
    [self didFinishPasswordFormExtraction:std::vector<autofill::FormData>()];
  }

  [self findPasswordFormsAndSendThemToPasswordStore];
}

- (void)webStateDestroyed:(web::WebState*)webState {
  DCHECK_EQ(_webState, webState);
  if (_webState) {
    _webState->RemoveObserver(_webStateObserverBridge.get());
    _webStateObserverBridge.reset();
    _webState = nullptr;
  }
  _passwordManagerDriver.reset();
  _passwordManager.reset();
  _passwordManagerClient.reset();
  _credentialManager.reset();
  _formGenerationData.clear();
  _isPasswordGenerated = NO;
}

#pragma mark - FormSuggestionProvider

- (id<FormSuggestionProvider>)suggestionProvider {
  return self;
}

- (void)checkIfSuggestionsAvailableForForm:(NSString*)formName
                           fieldIdentifier:(NSString*)fieldIdentifier
                                 fieldType:(NSString*)fieldType
                                      type:(NSString*)type
                                typedValue:(NSString*)typedValue
                                   frameID:(NSString*)frameID
                               isMainFrame:(BOOL)isMainFrame
                            hasUserGesture:(BOOL)hasUserGesture
                                  webState:(web::WebState*)webState
                         completionHandler:
                             (SuggestionsAvailableCompletion)completion {
  if (!GetPageURLAndCheckTrustLevel(webState, nullptr))
    return;
  [self.suggestionHelper
      checkIfSuggestionsAvailableForForm:formName
                         fieldIdentifier:fieldIdentifier
                               fieldType:fieldType
                                    type:type
                                 frameID:frameID
                             isMainFrame:isMainFrame
                                webState:webState
                       completionHandler:^(BOOL suggestionsAvailable) {
                         // Always display "Show All..." for password fields.
                         completion([fieldType isEqualToString:@"password"] ||
                                    suggestionsAvailable);
                       }];

  if (self.isPasswordGenerated &&
      [fieldIdentifier isEqualToString:self.passwordGeneratedIdentifier]) {
    // On other platforms, when the user clicks on generation field, we show
    // password in clear text. And the user has the possibility to edit it. On
    // iOS, it's harder to do (it's probably bad idea to change field type from
    // password to text). The decision was to give everything to the automatic
    // flow and avoid the manual flow, for a cleaner and simpler UI.
    if (typedValue.length < kMinimumLengthForEditedPassword) {
      self.isPasswordGenerated = NO;
      self.passwordGeneratedIdentifier = nil;
      self.passwordManager->OnPasswordNoLongerGenerated(
          self.passwordManagerDriver);
    } else {
      // Inject updated value to possibly update confirmation field.
      [self injectGeneratedPasswordForFormName:formName
                             generatedPassword:typedValue
                             completionHandler:nil];
    }
  }

  if (self.isPasswordGenerated) {
    // Always update, in case, for example, that username has been edited.
    self.passwordManager->UpdateGeneratedPasswordOnUserInput(
        SysNSStringToUTF16(formName), SysNSStringToUTF16(fieldIdentifier),
        SysNSStringToUTF16(typedValue));
  }
}

- (void)retrieveSuggestionsForForm:(NSString*)formName
                   fieldIdentifier:(NSString*)fieldIdentifier
                         fieldType:(NSString*)fieldType
                              type:(NSString*)type
                        typedValue:(NSString*)typedValue
                           frameID:(NSString*)frameID
                          webState:(web::WebState*)webState
                 completionHandler:(SuggestionsReadyCompletion)completion {
  if (!GetPageURLAndCheckTrustLevel(webState, nullptr))
    return;
  NSArray<FormSuggestion*>* rawSuggestions =
      [self.suggestionHelper retrieveSuggestionsWithFormName:formName
                                             fieldIdentifier:fieldIdentifier
                                                   fieldType:fieldType];

  NSMutableArray<FormSuggestion*>* suggestions = [NSMutableArray array];
  for (FormSuggestion* rawSuggestion in rawSuggestions) {
    [suggestions
        addObject:[FormSuggestion
                      suggestionWithValue:
                          [rawSuggestion.value
                              stringByAppendingString:kSuggestionSuffix]
                       displayDescription:rawSuggestion.displayDescription
                                     icon:nil
                               identifier:0]];
  }
  base::Optional<PasswordDropdownState> suggestion_state;
  if (suggestions.count) {
    suggestion_state = PasswordDropdownState::kStandard;
  }

  if ([self canGeneratePasswordForForm:formName
                       fieldIdentifier:fieldIdentifier
                             fieldType:fieldType]) {
    // Add "Suggest Password...".
    NSString* suggestPassword = GetNSString(IDS_IOS_SUGGEST_PASSWORD);
    [suggestions
        addObject:
            [FormSuggestion
                suggestionWithValue:suggestPassword
                 displayDescription:nil
                               icon:nil
                         identifier:autofill::
                                        POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY]];
    suggestion_state = PasswordDropdownState::kStandardGenerate;
  }

  if (suggestion_state) {
    LogPasswordDropdownShown(*suggestion_state,
                             _passwordManagerClient->IsIncognito());
  }

  completion([suggestions copy], self);
}

- (void)didSelectSuggestion:(FormSuggestion*)suggestion
                       form:(NSString*)formName
            fieldIdentifier:(NSString*)fieldIdentifier
                    frameID:(NSString*)frameID
          completionHandler:(SuggestionHandledCompletion)completion {
  switch (suggestion.identifier) {
    case autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY: {
      // Navigate to the settings list.
      [self.delegate displaySavedPasswordList];
      completion();
      password_manager::metrics_util::LogPasswordDropdownItemSelected(
          password_manager::metrics_util::PasswordDropdownSelectedOption::
              kShowAll,
          _passwordManagerClient->IsIncognito());
      return;
    }
    case autofill::POPUP_ITEM_ID_GENERATE_PASSWORD_ENTRY: {
      // Don't call completion because current siggestion state should remain
      // whether user injects a generated password or cancels.
      [self generatePasswordForFormName:formName
                        fieldIdentifier:fieldIdentifier];
      password_manager::metrics_util::LogPasswordDropdownItemSelected(
          password_manager::metrics_util::PasswordDropdownSelectedOption::
              kGenerate,
          _passwordManagerClient->IsIncognito());
      return;
    }
    default: {
      password_manager::metrics_util::LogPasswordDropdownItemSelected(
          password_manager::metrics_util::PasswordDropdownSelectedOption::
              kPassword,
          _passwordManagerClient->IsIncognito());
      DCHECK([suggestion.value hasSuffix:kSuggestionSuffix]);
      NSString* username = [suggestion.value
          substringToIndex:suggestion.value.length - kSuggestionSuffix.length];
      std::unique_ptr<password_manager::FillData> fillData =
          [self.suggestionHelper getFillDataForUsername:username];

      if (!fillData) {
        completion();
        return;
      }

      [self.formHelper fillPasswordFormWithFillData:*fillData
                                  completionHandler:^(BOOL success) {
                                    completion();
                                  }];
      break;
    }
  }
}

#pragma mark - PasswordManagerClientDelegate

- (web::WebState*)webState {
  return _webState;
}

- (ios::ChromeBrowserState*)browserState {
  return _webState ? ios::ChromeBrowserState::FromBrowserState(
                         _webState->GetBrowserState())
                   : nullptr;
}

- (PasswordManager*)passwordManager {
  return _passwordManager.get();
}

- (const GURL&)lastCommittedURL {
  return self.formHelper.lastCommittedURL;
}

- (void)showSavePasswordInfoBar:
    (std::unique_ptr<PasswordFormManagerForUI>)formToSave {
  [self showInfoBarForForm:std::move(formToSave)
               infoBarType:PasswordInfoBarType::SAVE];
}

- (void)showUpdatePasswordInfoBar:
    (std::unique_ptr<PasswordFormManagerForUI>)formToUpdate {
  [self showInfoBarForForm:std::move(formToUpdate)
               infoBarType:PasswordInfoBarType::UPDATE];
}

// Shows auto sign-in notification and schedules hiding it after 3 seconds.
// TODO(crbug.com/435048): Animate appearance.
- (void)showAutosigninNotification:
    (std::unique_ptr<autofill::PasswordForm>)formSignedIn {
  if (!_webState)
    return;

  // If a notification is already being displayed, hides the old one, then shows
  // the new one.
  if (self.notifyAutoSigninViewController) {
    _notifyAutoSigninTimer.Stop();
    [self hideAutosigninNotification];
  }

  // Creates view controller then shows the subview.
  self.notifyAutoSigninViewController =
      [[NotifyUserAutoSigninViewController alloc]
          initWithUsername:SysUTF16ToNSString(formSignedIn->username_value)
                   iconURL:formSignedIn->icon_url
          URLLoaderFactory:_webState->GetBrowserState()
                               ->GetSharedURLLoaderFactory()];
  TabIdTabHelper* tabIdHelper = TabIdTabHelper::FromWebState(_webState);
  if (![_delegate displaySignInNotification:self.notifyAutoSigninViewController
                                  fromTabId:tabIdHelper->tab_id()]) {
    // The notification was not shown. Store the password form in
    // |_pendingAutoSigninPasswordForm| to show the notification later.
    _pendingAutoSigninPasswordForm = std::move(formSignedIn);
    self.notifyAutoSigninViewController = nil;
    return;
  }

  // Hides notification after 3 seconds.
  __weak PasswordController* weakSelf = self;
  _notifyAutoSigninTimer.Start(
      FROM_HERE, base::TimeDelta::FromSeconds(kNotifyAutoSigninDuration),
      base::BindRepeating(^{
        [weakSelf hideAutosigninNotification];
      }));
}

- (void)showPasswordBreachForLeakType:(CredentialLeakType)leakType
                                  URL:(const GURL&)URL {
  [self.dispatcher showPasswordBreachForLeakType:leakType URL:URL];
}

#pragma mark - PasswordManagerDriverDelegate

- (void)fillPasswordForm:(const autofill::PasswordFormFillData&)formData
       completionHandler:(void (^)(BOOL))completionHandler {
  [self.suggestionHelper processWithPasswordFormFillData:formData];
  [self.formHelper fillPasswordForm:formData
                  completionHandler:completionHandler];
}

- (void)onNoSavedCredentials {
  [self.suggestionHelper processWithNoSavedCredentials];
}

- (PasswordGenerationFrameHelper*)passwordGenerationHelper {
  return _passwordGenerationHelper.get();
}

- (void)formEligibleForGenerationFound:(const PasswordFormGenerationData&)form {
  _formGenerationData[form.form_name] = form;
}

#pragma mark - PasswordFormHelperDelegate

- (void)formHelper:(PasswordFormHelper*)formHelper
     didSubmitForm:(const FormData&)form
       inMainFrame:(BOOL)inMainFrame {
  // TODO(crbug.com/949519): remove using PasswordForm completely when the old
  // parser is gone.
  PasswordForm password_form;
  password_form.form_data = form;
  if (inMainFrame) {
    self.passwordManager->OnPasswordFormSubmitted(self.passwordManagerDriver,
                                                  password_form);
  } else {
    // Show a save prompt immediately because for iframes it is very hard to
    // figure out correctness of password forms submission.
    self.passwordManager->OnPasswordFormSubmittedNoChecksForiOS(
        self.passwordManagerDriver, password_form);
  }
}

#pragma mark - PasswordSuggestionHelperDelegate

- (void)suggestionHelperShouldTriggerFormExtraction:
    (PasswordSuggestionHelper*)suggestionHelper {
  [self findPasswordFormsAndSendThemToPasswordStore];
}

#pragma mark - Private methods

- (void)didFinishPasswordFormExtraction:(const std::vector<FormData>&)forms {
  // Do nothing if |self| has been detached.
  if (!self.passwordManager)
    return;

  // TODO(crbug.com/949519): remove using PasswordForm completely when the old
  // parser is gone.
  std::vector<PasswordForm> password_forms(forms.size());
  for (size_t i = 0; i < forms.size(); ++i)
    password_forms[i].form_data = forms[i];

  if (!password_forms.empty()) {
    [self.suggestionHelper updateStateOnPasswordFormExtracted];

    // Invoke the password manager callback to autofill password forms
    // on the loaded page.
    self.passwordManager->OnPasswordFormsParsed(self.passwordManagerDriver,
                                                password_forms);
  } else {
    [self onNoSavedCredentials];
  }
  // Invoke the password manager callback to check if password was
  // accepted or rejected. If accepted, infobar is presented. If
  // rejected, the provisionally saved password is deleted. On Chrome
  // w/ a renderer, it is the renderer who calls OnPasswordFormsParsed()
  // and OnPasswordFormsRendered(). Bling has to improvised a bit on the
  // ordering of these two calls.
  self.passwordManager->OnPasswordFormsRendered(self.passwordManagerDriver,
                                                password_forms, true);
}

- (void)findPasswordFormsAndSendThemToPasswordStore {
  // Read all password forms from the page and send them to the password
  // manager.
  __weak PasswordController* weakSelf = self;
  [self.formHelper findPasswordFormsWithCompletionHandler:^(
                       const std::vector<autofill::FormData>& forms) {
    [weakSelf didFinishPasswordFormExtraction:forms];
  }];
}

- (void)showInfoBarForForm:(std::unique_ptr<PasswordFormManagerForUI>)form
               infoBarType:(PasswordInfoBarType)type {
  if (!_webState)
    return;

  bool isSyncUser = false;
  if (self.browserState) {
    syncer::SyncService* sync_service =
        ProfileSyncServiceFactory::GetForBrowserState(self.browserState);
    isSyncUser = password_bubble_experiment::IsSmartLockUser(sync_service);
  }
  infobars::InfoBarManager* infoBarManager =
      InfoBarManagerImpl::FromWebState(_webState);

  switch (type) {
    case PasswordInfoBarType::SAVE: {
      auto delegate = std::make_unique<IOSChromeSavePasswordInfoBarDelegate>(
          isSyncUser, /*password_update*/ false, std::move(form));
      delegate->set_dispatcher(self.dispatcher);

      if (IsInfobarUIRebootEnabled()) {
        InfobarPasswordCoordinator* coordinator =
            [[InfobarPasswordCoordinator alloc]
                initWithInfoBarDelegate:delegate.get()
                                   type:InfobarType::kInfobarTypePasswordSave];
        infoBarManager->AddInfoBar(
            std::make_unique<InfoBarIOS>(coordinator, std::move(delegate)));
      } else {
        IOSPasswordInfoBarController* controller =
            [[IOSPasswordInfoBarController alloc]
                initWithInfoBarDelegate:delegate.get()];
        infoBarManager->AddInfoBar(
            std::make_unique<InfoBarIOS>(controller, std::move(delegate)));
      }
      break;
    }
    case PasswordInfoBarType::UPDATE: {
      if (IsInfobarUIRebootEnabled()) {
        auto delegate = std::make_unique<IOSChromeSavePasswordInfoBarDelegate>(
            isSyncUser, /*password_update*/ true, std::move(form));
        delegate->set_dispatcher(self.dispatcher);
        InfobarPasswordCoordinator* coordinator = [[InfobarPasswordCoordinator
            alloc]
            initWithInfoBarDelegate:delegate.get()
                               type:InfobarType::kInfobarTypePasswordUpdate];
        infoBarManager->AddInfoBar(
            std::make_unique<InfoBarIOS>(coordinator, std::move(delegate)));

      } else {
        IOSChromeUpdatePasswordInfoBarDelegate::Create(
            isSyncUser, infoBarManager, std::move(form),
            self.baseViewController, self.dispatcher);
      }
      break;
    }
  }
}

- (void)hideAutosigninNotification {
  [self.notifyAutoSigninViewController willMoveToParentViewController:nil];
  [self.notifyAutoSigninViewController.view removeFromSuperview];
  [self.notifyAutoSigninViewController removeFromParentViewController];
  self.notifyAutoSigninViewController = nil;
}

- (BOOL)canGeneratePasswordForForm:(NSString*)formName
                   fieldIdentifier:(NSString*)fieldIdentifier
                         fieldType:(NSString*)fieldType {
  if (_passwordManagerClient->IsIncognito() ||
      !_passwordManagerDriver->GetPasswordGenerationHelper()
           ->IsGenerationEnabled(
               /*log_debug_data*/ true))
    return NO;
  if (![fieldType isEqualToString:@"password"])
    return NO;
  const PasswordFormGenerationData* generation_data =
      [self getFormForGenerationFromFormName:formName];
  if (!generation_data)
    return NO;

  NSString* newPasswordIdentifier =
      SysUTF16ToNSString(generation_data->new_password_element);
  if ([fieldIdentifier isEqualToString:newPasswordIdentifier])
    return YES;

  // Don't show password generation if the field is 'confirm password'.
  return NO;
}

- (const PasswordFormGenerationData*)getFormForGenerationFromFormName:
    (NSString*)formName {
  const base::string16 name = SysNSStringToUTF16(formName);
  if (_formGenerationData.find(name) != _formGenerationData.end()) {
    return &_formGenerationData[name];
  }
  return nullptr;
}

- (void)generatePasswordForFormName:(NSString*)formName
                    fieldIdentifier:(NSString*)fieldIdentifier {
  if (![self getFormForGenerationFromFormName:formName])
    return;

  // TODO(crbug.com/886583): pass correct |max_length|.
  base::string16 generatedPassword =
      _passwordGenerationHelper->GeneratePassword([self lastCommittedURL], 0, 0,
                                                  0, nullptr);

  self.generatedPotentialPassword = SysUTF16ToNSString(generatedPassword);

  [[NSNotificationCenter defaultCenter]
      addObserver:self
         selector:@selector(updateGeneratePasswordStrings:)
             name:UIContentSizeCategoryDidChangeNotification
           object:nil];

  // TODO(crbug.com/886583): add eg tests
  self.actionSheetCoordinator = [[ActionSheetCoordinator alloc]
      initWithBaseViewController:self.baseViewController
                           title:@""
                         message:@""
                            rect:self.baseViewController.view.frame
                            view:self.baseViewController.view];
  self.actionSheetCoordinator.popoverArrowDirection = 0;
  self.actionSheetCoordinator.alertStyle =
      IsIPadIdiom() ? UIAlertControllerStyleAlert
                    : UIAlertControllerStyleActionSheet;

  // Set attributed text.
  [self updateGeneratePasswordStrings:self];

  __weak PasswordController* weakSelf = self;

  auto popupDismissed = ^{
    [weakSelf generatePasswordPopupDismissed];
  };

  [self.actionSheetCoordinator
      addItemWithTitle:GetNSString(IDS_IOS_USE_SUGGESTED_PASSWORD)
                action:^{
                  [weakSelf
                      injectGeneratedPasswordForFormName:formName
                                       generatedPassword:
                                           weakSelf.generatedPotentialPassword
                                       completionHandler:popupDismissed];
                }
                 style:UIAlertActionStyleDefault];

  [self.actionSheetCoordinator addItemWithTitle:GetNSString(IDS_CANCEL)
                                         action:popupDismissed
                                          style:UIAlertActionStyleCancel];

  // Set 'suggest' as preferred action, as per UX.
  self.actionSheetCoordinator.alertController.preferredAction =
      self.actionSheetCoordinator.alertController.actions[0];

  [self.actionSheetCoordinator start];
}

- (void)generatePasswordPopupDismissed {
  [self.actionSheetCoordinator stop];
  self.actionSheetCoordinator = nil;
  [[NSNotificationCenter defaultCenter] removeObserver:self];
  self.generatedPotentialPassword = nil;
}

- (void)updateGeneratePasswordStrings:(id)sender {
  NSString* title = [NSString
      stringWithFormat:@"%@\n%@\n ", GetNSString(IDS_IOS_SUGGESTED_PASSWORD),
                       self.generatedPotentialPassword];
  self.actionSheetCoordinator.attributedTitle =
      [[NSMutableAttributedString alloc]
          initWithString:title
              attributes:@{
                NSFontAttributeName :
                    [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]
              }];

  NSString* message = GetNSString(IDS_IOS_SUGGESTED_PASSWORD_HINT);
  self.actionSheetCoordinator.attributedMessage =
      [[NSMutableAttributedString alloc]
          initWithString:message
              attributes:@{
                NSFontAttributeName :
                    [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote]
              }];

  // TODO(crbug.com/886583): find a way to make action sheet coordinator
  // responsible for font size changes.
  [self.actionSheetCoordinator updateAttributedText];
}

- (void)injectGeneratedPasswordForFormName:(NSString*)formName
                         generatedPassword:(NSString*)generatedPassword
                         completionHandler:(void (^)())completionHandler {
  const autofill::PasswordFormGenerationData* generation_data =
      [self getFormForGenerationFromFormName:formName];
  if (!generation_data)
    return;
  NSString* newPasswordIdentifier =
      SysUTF16ToNSString(generation_data->new_password_element);
  NSString* confirmPasswordIdentifier =
      SysUTF16ToNSString(generation_data->confirmation_password_element);

  auto generatedPasswordInjected = ^(BOOL success) {
    auto passwordPresaved = ^(BOOL found, const autofill::FormData& form) {
      if (found) {
        self.passwordManager->PresaveGeneratedPassword(
            self.passwordManagerDriver, form,
            SysNSStringToUTF16(generatedPassword),
            SysNSStringToUTF16(newPasswordIdentifier));
      }
      // If the form isn't found, it disappeared between fillPasswordForm below
      // and here. There isn't much that can be done.
    };
    if (success) {
      [self.formHelper extractPasswordFormData:formName
                             completionHandler:passwordPresaved];
      self.isPasswordGenerated = YES;
      self.passwordGeneratedIdentifier = newPasswordIdentifier;
    }
    if (completionHandler)
      completionHandler();
  };

  [self.formHelper fillPasswordForm:formName
              newPasswordIdentifier:newPasswordIdentifier
          confirmPasswordIdentifier:confirmPasswordIdentifier
                  generatedPassword:generatedPassword
                  completionHandler:generatedPasswordInjected];
}

@end
