// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef IOS_WEB_VIEW_PUBLIC_CWV_AUTOFILL_CONTROLLER_DELEGATE_H_
#define IOS_WEB_VIEW_PUBLIC_CWV_AUTOFILL_CONTROLLER_DELEGATE_H_

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@class CWVAutofillController;
@class CWVAutofillForm;
@class CWVAutofillFormSuggestion;
@class CWVAutofillProfile;
@class CWVCreditCard;
@class CWVCreditCardSaver;
@class CWVCreditCardVerifier;
@class CWVPassword;
@class CWVCardUnmaskChallengeOption;
@class CWVVCNEnrollmentManager;
@class CWVCreditCardOTPVerifier;

// User decision for saving / updating an autofill profile.
typedef NS_ENUM(NSInteger, CWVAutofillProfileUserDecision) {
  // The user accepted the change.
  CWVAutofillProfileUserDecisionAccepted = 0,
  // The user declined the change.
  CWVAutofillProfileUserDecisionDeclined,
  // The user ignored the prompt.
  CWVAutofillProfileUserDecisionIgnored,
};

// User decision for saving / updating password.
// Note: CWVPasswordUserDecisionNever is only used in saving scenarios.
typedef NS_ENUM(NSInteger, CWVPasswordUserDecision) {
  CWVPasswordUserDecisionNotThisTime =
      0,                         // Do not save / update password this time.
  CWVPasswordUserDecisionNever,  // Never save password for this site.
  CWVPasswordUserDecisionYes,    // Save / update password.
};

// All possible leak type combinations.
// Keep up to date with password_manager::CredentialLeakFlags in
// components/password_manager/core/browser/leak_detection_dialog_utils.h.
typedef NS_OPTIONS(NSInteger, CWVPasswordLeakType) {
  // The leaked password is currently saved.
  CWVPasswordLeakTypeSaved = 1 << 0,
  // The leaked password is also used on other sites.
  CWVPasswordLeakTypeUsedOnOtherSites = 1 << 1,
  // The leaked password is synced to a remote store.
  CWVPasswordLeakTypeSynced = 1 << 2,
};

// All possible types of progress dialogs shown during an Autofill operation.
// This is kept up to date with autofill::AutofillProgressUiType in
// components/autofill/core/browser/ui/payments/autofill_progress_ui_type.h.
typedef NS_ENUM(NSInteger, CWVAutofillProgressDialogType) {
  // An invalid or unspecified type.
  CWVAutofillProgressDialogTypeUnspecified = 0,
  // Dialog for unmasking a Virtual Card (VCN).
  CWVAutofillProgressDialogTypeVirtualCardUnmask,
  // Dialog for unmasking a server-stored credit card.
  CWVAutofillProgressDialogTypeServerCardUnmask,
  // Dialog for unmasking or validating an International Bank Account Number
  // (IBAN).
  CWVAutofillProgressDialogTypeIbanUnmask,
  // Dialog shown while fetching a Virtual Card Number (VCN) for a 3DS flow.
  CWVAutofillProgressDialogType3DSFetchVCN,
  // Dialog shown while retrieving card information for an enrolled unmask flow.
  CWVAutofillProgressDialogTypeCardInfoRetrievalEnrolledUnmask,
  // Dialog shown while fetching a Virtual Card Number (VCN) for a Buy Now Pay
  // Later (BNPL) flow.
  CWVAutofillProgressDialogTypeBNPLFetchVCN,
  // Progress Ui Shown while extracting checkout amount for a Buy Now Pay Later
  // (BNPL) flow.
  CWVAutofillProgressDialogTypeBNPLAmountExtraction,
};

// A generic procedural block type that takes no arguments and returns nothing.
typedef void (^ProceduralBlock)(void);

// Protocol to receive callbacks related to autofill.
// |fieldIdentifier| identifies the html field. Generated by
// getFieldIdentifier utility function defined in form.ts.
// |fieldType| is the 'type' attribute of the html field.
// |formName| is the 'name' attribute of a html <form>.
// |value| is the 'value' attribute of the html field.
// Example:
// <form name='_formName_'>
//   <input id='_fieldIdentifier_' value='_value_' type='_fieldType_'>
// </form>
@protocol CWVAutofillControllerDelegate <NSObject>

@optional

// Called when a form field element receives a "focus" event.
// |userInitiated| is YES if field was focused as a result of user interaction.
- (void)autofillController:(CWVAutofillController*)autofillController
    didFocusOnFieldWithIdentifier:(NSString*)fieldIdentifier
                        fieldType:(NSInteger)fieldType
                         formName:(NSString*)formName
                          frameID:(NSString*)frameID
                            value:(NSString*)value
                    userInitiated:(BOOL)userInitiated;

// Called when a form field element receives an "input" event.
// |userInitiated| is YES if field received input as a result of user
// interaction.
- (void)autofillController:(CWVAutofillController*)autofillController
    didInputInFieldWithIdentifier:(NSString*)fieldIdentifier
                        fieldType:(NSInteger)fieldType
                         formName:(NSString*)formName
                          frameID:(NSString*)frameID
                            value:(NSString*)value
                    userInitiated:(BOOL)userInitiated;

// Called when a form field element receives a "blur" (un-focused) event.
// |userInitiated| is YES if field was blurred as a result of user interaction.
- (void)autofillController:(CWVAutofillController*)autofillController
    didBlurOnFieldWithIdentifier:(NSString*)fieldIdentifier
                       fieldType:(NSInteger)fieldType
                        formName:(NSString*)formName
                         frameID:(NSString*)frameID
                           value:(NSString*)value
                   userInitiated:(BOOL)userInitiated;

// TODO(crbug.com/477630132): Remove this method.
// DEPRECATED. Use
// `-autofillController:didSubmitFormWithName:frameID:perfectFilling:` instead.
// Called when a form was submitted. |userInitiated| is YES if form was
// submitted as a result of user interaction. |perfectFilling| is true if the
// user submitted the form without manually changing any of the autofilled data.
- (void)autofillController:(CWVAutofillController*)autofillController
     didSubmitFormWithName:(NSString*)formName
                   frameID:(NSString*)frameID
             userInitiated:(BOOL)userInitiated
            perfectFilling:(BOOL)perfectFilling;

// Called when a form was submitted. |perfectFilling| is true if the user
// submitted the form without manually changing any of the autofilled data.
- (void)autofillController:(CWVAutofillController*)autofillController
     didSubmitFormWithName:(NSString*)formName
                   frameID:(NSString*)frameID
            perfectFilling:(BOOL)perfectFilling;

// Called when |forms| are found in a frame with |frameID|.
// Will be called after initial load and after any form mutations.
// Always includes all forms in the frame.
- (void)autofillController:(CWVAutofillController*)autofillController
              didFindForms:(NSArray<CWVAutofillForm*>*)forms
                   frameID:(NSString*)frameID;

// Called when it is possible to save a new credit card. This is usually called
// after a new card was entered in a form and submitted.
// |saver| encapsulates information needed to assist with this save attempt.
// Life time of |saver| should be managed by the delegate.
- (void)autofillController:(CWVAutofillController*)autofillController
    saveCreditCardWithSaver:(CWVCreditCardSaver*)saver;

// Called when the user needs to use |verifier| to verify a credit card.
// Lifetime of |verifier| should be managed by the delegate.
- (void)autofillController:(CWVAutofillController*)autofillController
    verifyCreditCardWithVerifier:(CWVCreditCardVerifier*)verifier;

// Called when the user needs to use |OTPVerifier| to verify a credit card.
// Lifetime of |OTPVerifier| should be managed by the delegate.
- (void)autofillController:(CWVAutofillController*)autofillController
    verifyCreditCardWithOTPVerifier:(CWVCreditCardOTPVerifier*)OTPVerifier;

// Called when user needs to decide on whether or not to save the |password|.
// This can happen when user successfully logs into a web site with a new
// username.
// Pass user decision to |decisionHandler|. This block should be called only
// once if user made the decision, or not get called if user ignores the prompt.
// Not implementing it is equivalent of not calling |decisionHandler|.
- (void)autofillController:(CWVAutofillController*)autofillController
    decideSavePolicyForPassword:(CWVPassword*)password
                decisionHandler:
                    (void (^)(CWVPasswordUserDecision decision))decisionHandler;

// Called when user needs to decide on whether or not to update the |password|.
// This can happen when user successfully logs into a web site with a new
// password and an existing username.
// Pass user decision to |decisionHandler|. This block should be called only
// once if user made the decision, or not get called if user ignores the prompt.
// Not implementing it is equivalent of not calling |decisionHandler|.
- (void)autofillController:(CWVAutofillController*)autofillController
    decideUpdatePolicyForPassword:(CWVPassword*)password
                  decisionHandler:(void (^)(CWVPasswordUserDecision decision))
                                      decisionHandler;

// Called if a submitted username and password combination is determined to be
// leaked for |URL|. |leakType| provides additional context of the leak.
// Deprecated: Use |autofillController:notifyUserOfPasswordLeakOnURL:username:|.
- (void)autofillController:(CWVAutofillController*)autofillController
    notifyUserOfPasswordLeakOnURL:(NSURL*)URL
                         leakType:(CWVPasswordLeakType)leakType;

// Called if a submitted username and password combination is determined to be
// leaked for |URL|. |leakType| provides additional context of the leak.
// |username| The username whose password is leaked.
- (void)autofillController:(CWVAutofillController*)autofillController
    notifyUserOfPasswordLeakOnURL:(NSURL*)URL
                         leakType:(CWVPasswordLeakType)leakType
                         username:(NSString*)username;

// Called when the user taps on the suggest password suggestion when
// trying to sign up for a new account on a site. |generatedPassword| is a
// randomly generated password that, if accepted in |decisionHandler|, will be
// injected into the form. |decisionHandler| must be called.
- (void)autofillController:(CWVAutofillController*)autofillController
    suggestGeneratedPassword:(NSString*)generatedPassword
             decisionHandler:(void (^)(BOOL accept))decisionHandler;

// Called when the user should be prompted to save or update a profile.
// |newProfile| The new profile that is being considered.
// |oldProfile| The old profile, that if non-nil, will be overwritten.
// |decisionHandler| Must be called when the user makes a decision. If accepted,
// any property changes to |newProfile| will also be committed. This allows the
// user to make any edits if they wish.
// If this method is not implemented, |newProfile| will be automatically saved.
- (void)autofillController:(CWVAutofillController*)autofillController
    confirmSaveForNewAutofillProfile:(CWVAutofillProfile*)newProfile
                          oldProfile:(nullable CWVAutofillProfile*)oldProfile
                     decisionHandler:
                         (void (^)(CWVAutofillProfileUserDecision decision))
                             decisionHandler;

// Called when the user successfully logs into a web site with an existing
// password.
- (void)autofillControllerDidLoginWithExistingPassword:
    (CWVAutofillController*)autofillController;

// Called when the user needs to be shown a progress dialog during a payments
// autofill event. |type| determines the title and message of the dialog.
// |cancelAction| is an optional block to be executed if the user cancels
// the autofill process.
- (void)autofillController:(CWVAutofillController*)autofillController
    showProgressDialogOfType:(CWVAutofillProgressDialogType)type
                cancelAction:(ProceduralBlock)cancelAction;

// Called when the dialog shown via `showProgressDialogOfType` needs to be
// dismissed. |showConfirmation| A boolean indicating whether a confirmation
// message should be displayed before closing the dialog. |completion| An
// optional block to be executed once the dialog has been successfully closed.
- (void)autofillController:(CWVAutofillController*)autofillController
    closeProgressDialogWithConfirmation:(BOOL)showConfirmation
                             completion:(ProceduralBlock)completion;

// Called when the user needs to select a challenge option to verify a credit
// card unmasking attempt.
// |autofillController| The autofill controller requesting the selection.
// |options| An array of CWVCardUnmaskChallengeOption objects, each representing
// a method the user can choose to verify the card.
// |acceptBlock| The block to execute when the user selects an option. The
// |selectedOptionIdentifier| parameter passed to this block is the unique
// identifier from the chosen CWVCardUnmaskChallengeOption.
// |cancelBlock| The block to execute if the user cancels the selection process.
- (void)autofillController:(CWVAutofillController*)autofillController
    showUnmaskCreditCardAuthenticatorWithChallengeOptions:
        (NSArray<CWVCardUnmaskChallengeOption*>*)options
                                              acceptBlock:
                                                  (void (^)(
                                                      NSString*
                                                      selectedOptionIdentifier))
                                                      acceptBlock
                                              cancelBlock:
                                                  (ProceduralBlock)cancelBlock;

// Called to request application-specific risk data required for certain payment
// flows, such as unmasking a Virtual Card Number (VCN).
//
// The controller's |loadRiskData:| method is a router. It will first attempt
// to forward the request to an active |CWVCreditCardVerifier| or
// |CWVCreditCardSaver| instance. This delegate method serves as the fallback
// if called when neither of those objects are present. This is a common
// scenario for VCN flows where risk data is needed earlier in the process.
//
// |autofillController| The autofill controller requesting the data.
// |handler| The completion handler block that must be called with the
//   risk data to complete the operation.
- (void)autofillControllerLoadRiskData:
            (CWVAutofillController*)autofillController
                       riskDataHandler:(void (^)(NSString*))handler;

// Called when a credit card is eligible for Virtual Card Number (VCN)
// enrollment. This typically occurs after a card is successfully used or saved.
//
// The delegate should use the provided |enrollmentManager| to present the
// enrollment UI to the user. This flow includes displaying legal text and
// handling the user's decision to accept or decline.
- (void)autofillController:(CWVAutofillController*)autofillController
    enrollCreditCardWithVCNEnrollmentManager:
        (CWVVCNEnrollmentManager*)enrollmentManager;

@end

NS_ASSUME_NONNULL_END

#endif  // IOS_WEB_VIEW_PUBLIC_CWV_AUTOFILL_CONTROLLER_DELEGATE_H_
