// 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 "components/password_manager/ios/password_form_helper.h"

#include <stddef.h>

#include "base/strings/sys_string_conversions.h"
#include "base/values.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/ios/browser/autofill_switches.h"
#include "components/autofill/ios/browser/autofill_util.h"
#include "components/password_manager/core/browser/form_parsing/ios_form_parser.h"
#include "components/password_manager/ios/account_select_fill_data.h"
#include "components/password_manager/ios/js_password_manager.h"
#import "ios/web/public/web_state/web_frame.h"
#import "ios/web/public/web_state/web_state.h"

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

using autofill::FormData;
using autofill::PasswordForm;
using password_manager::GetPageURLAndCheckTrustLevel;
using password_manager::FillData;
using password_manager::SerializePasswordFormFillData;

namespace password_manager {
bool GetPageURLAndCheckTrustLevel(web::WebState* web_state,
                                  GURL* __nullable page_url) {
  auto trustLevel = web::URLVerificationTrustLevel::kNone;
  GURL dummy;
  if (!page_url) {
    page_url = &dummy;
  }
  *page_url = web_state->GetCurrentURL(&trustLevel);
  return trustLevel == web::URLVerificationTrustLevel::kAbsolute;
}
}  // namespace password_manager

namespace {
// Script command prefix for form changes. Possible command to be sent from
// injected JS is 'passwordForm.submitButtonClick'.
constexpr char kCommandPrefix[] = "passwordForm";
}  // namespace

@interface PasswordFormHelper ()

@property(nonatomic, weak) id<PasswordFormHelperDelegate> delegate;

// Handler for injected JavaScript callbacks.
- (BOOL)handleScriptCommand:(const base::DictionaryValue&)JSONCommand;

// Finds the currently submitted password form named |formName| and calls
// |completionHandler| with the populated data structure. |found| is YES if the
// current form was found successfully, NO otherwise.
- (void)extractSubmittedPasswordForm:(const std::string&)formName
                   completionHandler:
                       (void (^)(BOOL found,
                                 const PasswordForm& form))completionHandler;

// Parses the |jsonString| which contatins the password forms found on a web
// page to populate the |forms| vector.
- (void)getPasswordFormsFromJSON:(NSString*)jsonString
                         pageURL:(const GURL&)pageURL
                           forms:(std::vector<autofill::PasswordForm>*)forms;

// Autofills |username| and |password| into the form specified by |formData|,
// invoking |completionHandler| when finished with YES if successful and
// NO otherwise. |completionHandler| may be nil.
- (void)fillPasswordForm:(const autofill::PasswordFormFillData&)formData
            withUsername:(const base::string16&)username
                password:(const base::string16&)password
       completionHandler:(nullable void (^)(BOOL))completionHandler;

@end

// Category for test only.
@interface PasswordFormHelper (Testing)

// Replaces JsPasswordManager for test.
- (void)setJsPasswordManager:(JsPasswordManager*)jsPasswordManager;

@end

@implementation PasswordFormHelper {
  // 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;

  // Bridge to observe form activity in |_webState|.
  std::unique_ptr<autofill::FormActivityObserverBridge>
      _formActivityObserverBridge;
}

#pragma mark - Properties

@synthesize delegate = _delegate;
@synthesize jsPasswordManager = _jsPasswordManager;

- (const GURL&)lastCommittedURL {
  return _webState ? _webState->GetLastCommittedURL() : GURL::EmptyGURL();
}

#pragma mark - Initialization

- (instancetype)initWithWebState:(web::WebState*)webState
                        delegate:(id<PasswordFormHelperDelegate>)delegate {
  self = [super init];
  if (self) {
    DCHECK(webState);
    _webState = webState;
    _delegate = delegate;
    _webStateObserverBridge =
        std::make_unique<web::WebStateObserverBridge>(self);
    _webState->AddObserver(_webStateObserverBridge.get());
    _formActivityObserverBridge =
        std::make_unique<autofill::FormActivityObserverBridge>(_webState, self);
    _jsPasswordManager = [[JsPasswordManager alloc]
        initWithReceiver:_webState->GetJSInjectionReceiver()];

    __weak PasswordFormHelper* weakSelf = self;
    auto callback = base::BindRepeating(
        ^bool(const base::DictionaryValue& JSON, const GURL& originURL,
              bool interacting, bool isMainFrame, web::WebFrame* senderFrame) {
          if (!isMainFrame) {
            // Passwords is only supported on main frame.
            return false;
          }
          // |originURL| and |interacting| aren't used.
          return [weakSelf handleScriptCommand:JSON];
        });
    _webState->AddScriptCommandCallback(callback, kCommandPrefix);
  }
  return self;
}

#pragma mark - Dealloc

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

#pragma mark - CRWWebStateObserver

- (void)webStateDestroyed:(web::WebState*)webState {
  DCHECK_EQ(_webState, webState);
  if (_webState) {
    _webState->RemoveScriptCommandCallback(kCommandPrefix);
    _webState->RemoveObserver(_webStateObserverBridge.get());
    _webState = nullptr;
  }
  _webStateObserverBridge.reset();
  _formActivityObserverBridge.reset();
}

#pragma mark - FormActivityObserver

- (void)webState:(web::WebState*)webState
    didSubmitDocumentWithFormNamed:(const std::string&)formName
                          withData:(const std::string&)formData
                    hasUserGesture:(BOOL)hasUserGesture
                   formInMainFrame:(BOOL)formInMainFrame
                           inFrame:(web::WebFrame*)frame {
  DCHECK_EQ(_webState, webState);
  GURL pageURL = webState->GetLastCommittedURL();
  if (autofill::switches::IsAutofillIFrameMessagingEnabled() &&
      pageURL.GetOrigin() != frame->GetSecurityOrigin()) {
    // Passwords is only supported on main frame and iframes with the same
    // origin.
    return;
  }
  __weak PasswordFormHelper* weakSelf = self;
  // This code is racing against the new page loading and will not get the
  // password form data if the page has changed. In most cases this code wins
  // the race.
  // TODO(crbug.com/418827): Fix this by passing in more data from the JS side.
  id completionHandler = ^(BOOL found, const autofill::PasswordForm& form) {
    PasswordFormHelper* strongSelf = weakSelf;
    id<PasswordFormHelperDelegate> strongDelegate = strongSelf.delegate;
    if (!strongSelf || !strongSelf->_webState || !strongDelegate) {
      return;
    }
    [strongDelegate formHelper:strongSelf
                 didSubmitForm:form
                   inMainFrame:formInMainFrame];
  };
  // TODO(crbug.com/418827): Use |formData| instead of extracting form again.
  [self extractSubmittedPasswordForm:formName
                   completionHandler:completionHandler];
}

#pragma mark - Private methods

- (BOOL)handleScriptCommand:(const base::DictionaryValue&)JSONCommand {
  std::string command;
  if (!JSONCommand.GetString("command", &command)) {
    return NO;
  }

  if (command != "passwordForm.submitButtonClick") {
    return NO;
  }

  GURL pageURL;
  if (!GetPageURLAndCheckTrustLevel(_webState, &pageURL)) {
    return NO;
  }

  FormData formData;
  if (!autofill::ExtractFormData(JSONCommand, false, base::string16(), pageURL,
                                 pageURL.GetOrigin(), &formData)) {
    return NO;
  }

  std::unique_ptr<PasswordForm> form =
      ParseFormData(formData, password_manager::FormParsingMode::SAVING);
  if (!form) {
    return NO;
  }

  if (_webState && self.delegate) {
    [self.delegate formHelper:self didSubmitForm:*form inMainFrame:YES];
    return YES;
  }

  return NO;
}

- (void)extractSubmittedPasswordForm:(const std::string&)formName
                   completionHandler:
                       (void (^)(BOOL found,
                                 const PasswordForm& form))completionHandler {
  DCHECK(completionHandler);

  if (!_webState) {
    return;
  }

  GURL pageURL;
  if (!GetPageURLAndCheckTrustLevel(_webState, &pageURL)) {
    completionHandler(NO, PasswordForm());
    return;
  }

  id extractSubmittedFormCompletionHandler = ^(NSString* jsonString) {
    std::unique_ptr<base::Value> formValue = autofill::ParseJson(jsonString);
    if (!formValue) {
      completionHandler(NO, PasswordForm());
      return;
    }

    FormData formData;
    if (!autofill::ExtractFormData(*formValue, false, base::string16(), pageURL,
                                   pageURL.GetOrigin(), &formData)) {
      completionHandler(NO, PasswordForm());
      return;
    }

    std::unique_ptr<PasswordForm> form =
        ParseFormData(formData, password_manager::FormParsingMode::SAVING);
    if (!form) {
      completionHandler(NO, PasswordForm());
      return;
    }

    completionHandler(YES, *form);
  };

  [self.jsPasswordManager extractForm:base::SysUTF8ToNSString(formName)
                    completionHandler:extractSubmittedFormCompletionHandler];
}

- (void)getPasswordFormsFromJSON:(NSString*)jsonString
                         pageURL:(const GURL&)pageURL
                           forms:(std::vector<autofill::PasswordForm>*)forms {
  std::vector<autofill::FormData> formsData;
  // Password is only available on main frame.
  if (!autofill::ExtractFormsData(jsonString, false, base::string16(), pageURL,
                                  pageURL.GetOrigin(), &formsData)) {
    return;
  }

  for (const auto& formData : formsData) {
    std::unique_ptr<PasswordForm> form =
        ParseFormData(formData, password_manager::FormParsingMode::FILLING);
    if (form) {
      forms->push_back(*form);
    }
  }
}

- (void)fillPasswordForm:(const autofill::PasswordFormFillData&)formData
            withUsername:(const base::string16&)username
                password:(const base::string16&)password
       completionHandler:(nullable void (^)(BOOL))completionHandler {
  if (formData.origin.GetOrigin() != self.lastCommittedURL.GetOrigin()) {
    if (completionHandler) {
      completionHandler(NO);
    }
    return;
  }

  // Send JSON over to the web view.
  [self.jsPasswordManager
       fillPasswordForm:SerializePasswordFormFillData(formData)
           withUsername:base::SysUTF16ToNSString(username)
               password:base::SysUTF16ToNSString(password)
      completionHandler:^(BOOL result) {
        if (completionHandler) {
          completionHandler(result);
        }
      }];
}

#pragma mark - Private methods for test only

- (void)setJsPasswordManager:(JsPasswordManager*)jsPasswordManager {
  _jsPasswordManager = jsPasswordManager;
}

#pragma mark - Public methods

- (void)findPasswordFormsWithCompletionHandler:
    (void (^)(const std::vector<autofill::PasswordForm>&))completionHandler {
  if (!_webState) {
    return;
  }

  GURL pageURL;
  if (!GetPageURLAndCheckTrustLevel(_webState, &pageURL)) {
    return;
  }

  __weak PasswordFormHelper* weakSelf = self;
  [self.jsPasswordManager findPasswordFormsWithCompletionHandler:^(
                              NSString* jsonString) {
    std::vector<autofill::PasswordForm> forms;
    [weakSelf getPasswordFormsFromJSON:jsonString pageURL:pageURL forms:&forms];
    completionHandler(forms);
  }];
}

- (void)fillPasswordForm:(const autofill::PasswordFormFillData&)formData
       completionHandler:(nullable void (^)(BOOL))completionHandler {
  // Don't fill immediately if waiting for the user to type a username.
  if (formData.wait_for_username) {
    if (completionHandler) {
      completionHandler(NO);
    }
    return;
  }

  [self fillPasswordForm:formData
            withUsername:formData.username_field.value
                password:formData.password_field.value
       completionHandler:completionHandler];
}

- (void)fillPasswordForm:(NSString*)formName
        newPasswordIdentifier:(NSString*)newPasswordIdentifier
    confirmPasswordIdentifier:(NSString*)confirmPasswordIdentifier
            generatedPassword:(NSString*)generatedPassword
            completionHandler:(nullable void (^)(BOOL))completionHandler {
  // Send JSON over to the web view.
  [self.jsPasswordManager fillPasswordForm:formName
                     newPasswordIdentifier:newPasswordIdentifier
                 confirmPasswordIdentifier:confirmPasswordIdentifier
                         generatedPassword:generatedPassword
                         completionHandler:^(BOOL result) {
                           if (completionHandler) {
                             completionHandler(result);
                           }
                         }];
}

- (void)fillPasswordFormWithFillData:(const password_manager::FillData&)fillData
                   completionHandler:
                       (nullable void (^)(BOOL))completionHandler {
  [self.jsPasswordManager
       fillPasswordForm:SerializeFillData(fillData)
           withUsername:base::SysUTF16ToNSString(fillData.username_value)
               password:base::SysUTF16ToNSString(fillData.password_value)
      completionHandler:^(BOOL result) {
        if (completionHandler) {
          completionHandler(result);
        }
      }];
}

- (void)findAndFillPasswordFormsWithUserName:(NSString*)username
                                    password:(NSString*)password
                           completionHandler:
                               (nullable void (^)(BOOL))completionHandler {
  __weak PasswordFormHelper* weakSelf = self;
  [self findPasswordFormsWithCompletionHandler:^(
            const std::vector<autofill::PasswordForm>& forms) {
    PasswordFormHelper* strongSelf = weakSelf;
    for (const auto& form : forms) {
      autofill::PasswordFormFillData formData;
      std::map<base::string16, const autofill::PasswordForm*> matches;
      // Initialize |matches| to satisfy the expectation from
      // InitPasswordFormFillData() that the preferred match (3rd parameter)
      // should be one of the |matches|.
      matches.insert(std::make_pair(form.username_value, &form));
      autofill::InitPasswordFormFillData(form, matches, &form, false,
                                         &formData);
      [strongSelf fillPasswordForm:formData
                      withUsername:base::SysNSStringToUTF16(username)
                          password:base::SysNSStringToUTF16(password)
                 completionHandler:completionHandler];
    }
  }];
}

@end
