// Copyright 2017 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/autofill/ios/browser/autofill_util.h"

#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/mac/foundation_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "components/autofill/core/browser/autofill_field.h"
#include "components/autofill/core/common/autofill_util.h"
#include "components/autofill/core/common/form_data.h"
#include "components/autofill/core/common/form_field_data.h"
#include "components/autofill/ios/browser/autofill_switches.h"
#import "ios/web/public/navigation_item.h"
#import "ios/web/public/navigation_manager.h"
#include "ios/web/public/ssl_status.h"
#import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
#include "url/gurl.h"
#include "url/origin.h"

namespace {
// The timeout for any JavaScript call in this file.
// It is only used if IsAutofillIFrameMessagingEnabled is enabled.
const int64_t kJavaScriptExecutionTimeoutInSeconds = 5;
}

namespace autofill {

bool IsContextSecureForWebState(web::WebState* web_state) {
  // This implementation differs slightly from other platforms. Other platforms'
  // implementations check for the presence of active mixed content, but because
  // the iOS web view blocks active mixed content without an option to run it,
  // there is no need to check for active mixed content here.
  web::NavigationManager* manager = web_state->GetNavigationManager();
  const web::NavigationItem* nav_item = manager->GetLastCommittedItem();
  if (!nav_item)
    return false;

  const web::SSLStatus& ssl = nav_item->GetSSL();
  return nav_item->GetURL().SchemeIsCryptographic() && ssl.certificate &&
         (!net::IsCertStatusError(ssl.cert_status) ||
          net::IsCertStatusMinorError(ssl.cert_status));
}

std::unique_ptr<base::Value> ParseJson(NSString* json_string) {
  // Convert JSON string to JSON object |JSONValue|.
  int error_code = 0;
  std::string error_message;
  std::unique_ptr<base::Value> json_value(base::JSONReader::ReadAndReturnError(
      base::SysNSStringToUTF8(json_string), base::JSON_PARSE_RFC, &error_code,
      &error_message));
  if (error_code)
    return nullptr;

  return json_value;
}

bool ExtractFormsData(NSString* forms_json,
                      bool filtered,
                      const base::string16& form_name,
                      const GURL& main_frame_url,
                      const GURL& frame_origin,
                      std::vector<FormData>* forms_data) {
  DCHECK(forms_data);
  std::unique_ptr<base::Value> forms_value = ParseJson(forms_json);
  if (!forms_value)
    return false;

  // Returned data should be a list of forms.
  const base::ListValue* forms_list = nullptr;
  if (!forms_value->GetAsList(&forms_list))
    return false;

  // Iterate through all the extracted forms and copy the data from JSON into
  // AutofillManager structures.
  for (const auto& form_dict : *forms_list) {
    autofill::FormData form;
    if (ExtractFormData(form_dict, filtered, form_name, main_frame_url,
                        frame_origin, &form))
      forms_data->push_back(std::move(form));
  }
  return true;
}

bool ExtractFormData(const base::Value& form_value,
                     bool filtered,
                     const base::string16& form_name,
                     const GURL& main_frame_url,
                     const GURL& form_frame_origin,
                     autofill::FormData* form_data) {
  DCHECK(form_data);
  // Each form should be a JSON dictionary.
  const base::DictionaryValue* form_dictionary = nullptr;
  if (!form_value.GetAsDictionary(&form_dictionary))
    return false;

  // Form data is copied into a FormData object field-by-field.
  if (!form_dictionary->GetString("name", &form_data->name))
    return false;
  if (filtered && form_name != form_data->name)
    return false;

  // Origin is mandatory.
  base::string16 origin;
  if (!form_dictionary->GetString("origin", &origin))
    return false;

  // Use GURL object to verify origin of host frame URL.
  form_data->origin = GURL(origin);
  if (form_data->origin.GetOrigin() != form_frame_origin)
    return false;

  // main_frame_origin is used for logging UKM.
  form_data->main_frame_origin = url::Origin::Create(main_frame_url);

  // Action is optional.
  base::string16 action;
  form_dictionary->GetString("action", &action);
  form_data->action = GURL(action);

  // Optional fields.
  form_dictionary->GetString("name_attribute", &form_data->name_attribute);
  form_dictionary->GetString("id_attribute", &form_data->id_attribute);
  form_dictionary->GetBoolean("is_form_tag", &form_data->is_form_tag);
  form_dictionary->GetBoolean("is_formless_checkout",
                              &form_data->is_formless_checkout);

  // Field list (mandatory) is extracted.
  const base::ListValue* fields_list = nullptr;
  if (!form_dictionary->GetList("fields", &fields_list))
    return false;
  for (const auto& field_dict : *fields_list) {
    const base::DictionaryValue* field;
    autofill::FormFieldData field_data;
    if (field_dict.GetAsDictionary(&field) &&
        ExtractFormFieldData(*field, &field_data)) {
      form_data->fields.push_back(std::move(field_data));
    } else {
      return false;
    }
  }
  return true;
}

bool ExtractFormFieldData(const base::DictionaryValue& field,
                          autofill::FormFieldData* field_data) {
  if (!field.GetString("name", &field_data->name) ||
      !field.GetString("identifier", &field_data->unique_id) ||
      !field.GetString("form_control_type", &field_data->form_control_type)) {
    return false;
  }

  // Optional fields.
  field.GetString("name_attribute", &field_data->name_attribute);
  field.GetString("id_attribute", &field_data->id_attribute);
  field.GetString("label", &field_data->label);
  field.GetString("value", &field_data->value);
  field.GetString("autocomplete_attribute",
                  &field_data->autocomplete_attribute);
  field.GetBoolean("is_autofilled", &field_data->is_autofilled);

  int max_length = 0;
  if (field.GetInteger("max_length", &max_length))
    field_data->max_length = max_length;

  // TODO(crbug.com/427614): Extract |is_checked|.
  bool is_checkable = false;
  field.GetBoolean("is_checkable", &is_checkable);
  autofill::SetCheckStatus(field_data, is_checkable, false);

  field.GetBoolean("is_focusable", &field_data->is_focusable);
  field.GetBoolean("should_autocomplete", &field_data->should_autocomplete);

  // ROLE_ATTRIBUTE_OTHER is the default value. The only other value as of this
  // writing is ROLE_ATTRIBUTE_PRESENTATION.
  int role = 0;
  if (field.GetInteger("role", &role) &&
      role == autofill::AutofillField::ROLE_ATTRIBUTE_PRESENTATION) {
    field_data->role = autofill::AutofillField::ROLE_ATTRIBUTE_PRESENTATION;
  }

  // TODO(crbug.com/427614): Extract |text_direction|.

  // Load option values where present.
  const base::ListValue* option_values = nullptr;
  if (field.GetList("option_values", &option_values)) {
    for (const auto& optionValue : *option_values) {
      base::string16 value;
      if (optionValue.GetAsString(&value))
        field_data->option_values.push_back(std::move(value));
    }
  }

  // Load option contents where present.
  const base::ListValue* option_contents = nullptr;
  if (field.GetList("option_contents", &option_contents)) {
    for (const auto& option_content : *option_contents) {
      base::string16 content;
      if (option_content.GetAsString(&content))
        field_data->option_contents.push_back(std::move(content));
    }
  }

  return field_data->option_values.size() == field_data->option_contents.size();
}

void ExecuteJavaScriptFunction(const std::string& name,
                               const std::vector<base::Value>& parameters,
                               web::WebFrame* frame,
                               CRWJSInjectionReceiver* js_injection_receiver,
                               base::OnceCallback<void(NSString*)> callback) {
  if (autofill::switches::IsAutofillIFrameMessagingEnabled()) {
    ExecuteJavaScriptFunctionInWebFrame(name, parameters, frame,
                                        std::move(callback));
  } else {
    ExecuteJavaScriptFunctionInWebState(name, parameters, js_injection_receiver,
                                        std::move(callback));
  }
}

void ExecuteJavaScriptFunctionInWebFrame(
    const std::string& name,
    const std::vector<base::Value>& parameters,
    web::WebFrame* frame,
    base::OnceCallback<void(NSString*)> cb) {
  __block base::OnceCallback<void(NSString*)> callback = std::move(cb);

  if (!frame) {
    if (!callback.is_null()) {
      std::move(callback).Run(nil);
    }
    return;
  }
  DCHECK(frame->CanCallJavaScriptFunction());
  if (!callback.is_null()) {
    bool called = frame->CallJavaScriptFunction(
        name, parameters, base::BindOnce(^(const base::Value* res) {
          NSString* result = nil;
          if (res && res->is_string()) {
            result = base::SysUTF8ToNSString(res->GetString());
          }
          std::move(callback).Run(result);
        }),
        base::TimeDelta::FromSeconds(kJavaScriptExecutionTimeoutInSeconds));
    if (!called) {
      std::move(callback).Run(nil);
    }
  } else {
    frame->CallJavaScriptFunction(name, parameters);
  }
}

void ExecuteJavaScriptFunctionInWebState(
    const std::string& name,
    const std::vector<base::Value>& parameters,
    CRWJSInjectionReceiver* js_injection_receiver,
    base::OnceCallback<void(NSString*)> cb) {
  __block base::OnceCallback<void(NSString*)> callback = std::move(cb);

  std::string function_name = "__gCrWeb." + name;
  NSMutableArray* json_parameters = [[NSMutableArray alloc] init];
  for (auto& value : parameters) {
    std::string dataString;
    base::JSONWriter::Write(value, &dataString);
    [json_parameters addObject:base::SysUTF8ToNSString(dataString)];
  }
  NSString* command = [NSString
      stringWithFormat:@"%s(%@);", function_name.c_str(),
                       [json_parameters componentsJoinedByString:@", "]];
  if (!callback.is_null()) {
    [js_injection_receiver
        executeJavaScript:command
        completionHandler:^(id result, NSError* error) {
          std::move(callback).Run(base::mac::ObjCCastStrict<NSString>(result));
        }];
  } else {
    [js_injection_receiver executeJavaScript:command completionHandler:nil];
  }
}

}  // namespace autofill
