// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The SFC licenses this file
// to you under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "NewSessionCommandHandler.h"
#include "errorcodes.h"
#include "logging.h"
#include "../Alert.h"
#include "../Browser.h"
#include "../BrowserFactory.h"
#include "../IECommandExecutor.h"
#include "../InputManager.h"
#include "../ProxyManager.h"
#include "../WebDriverConstants.h"

namespace webdriver {

NewSessionCommandHandler::NewSessionCommandHandler(void) {
}

NewSessionCommandHandler::~NewSessionCommandHandler(void) {
}

void NewSessionCommandHandler::ExecuteInternal(
    const IECommandExecutor& executor,
    const ParametersMap& command_parameters,
    Response* response) {
  Json::Value returned_capabilities;
  std::string error_message = "";

  // Find W3C capabilities first.
  IECommandExecutor& mutable_executor = const_cast<IECommandExecutor&>(executor);

  ParametersMap::const_iterator it = command_parameters.find("capabilities");
  if (it != command_parameters.end()) {
    LOG(DEBUG) << "Found W3C capabilities structure";
    Json::Value validated_capabilities = this->ValidateArguments(it->second,
                                                                 &error_message);
    if (validated_capabilities.size() == 0) {
      // validated_capabilities returns an array with validated capabilities
      // in it. If there are no entries in the array, then something failed
      // validation. The error_message string will tell us what.
      mutable_executor.set_is_valid(false);
      response->SetErrorResponse(ERROR_INVALID_ARGUMENT, error_message);
      return;
    }
    error_message = "";
    returned_capabilities = this->ProcessCapabilities(executor,
                                                      validated_capabilities,
                                                      &error_message);
  } else {
    error_message = "No property named 'capabilities' found in new session request body.";
    mutable_executor.set_is_valid(false);
    response->SetErrorResponse(ERROR_INVALID_ARGUMENT, error_message);
    return;
  }

  if (returned_capabilities.isNull()) {
    // The browser was not created successfully, therefore the
    // session must be marked as invalid so the server can
    // properly shut it down.
    mutable_executor.set_is_valid(false);
    response->SetErrorResponse(ERROR_SESSION_NOT_CREATED, error_message);
    return;
  }

  error_message = "";
  int result_code = mutable_executor.CreateNewBrowser(&error_message);
  if (result_code != WD_SUCCESS) {
    // The browser was not created successfully, therefore the
    // session must be marked as invalid so the server can
    // properly shut it down.
    mutable_executor.set_is_valid(false);
    response->SetErrorResponse(ERROR_SESSION_NOT_CREATED,
        "Unexpected error launching Internet Explorer. " + error_message);
    return;
  }
  Json::Value new_session_response_object;
  new_session_response_object["sessionId"] = executor.session_id();
  new_session_response_object["capabilities"] = returned_capabilities;
  response->SetSuccessResponse(new_session_response_object);
}

Json::Value NewSessionCommandHandler::GetCapability(
    const Json::Value& capabilities,
    const std::string& capability_name,
    const Json::ValueType& expected_capability_type,
    const Json::Value& default_value) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::GetCapability "
             << "for capability " << capability_name;
  Json::Value capability_value = capabilities.get(capability_name, default_value);
  if (!this->IsEquivalentType(capability_value.type(), expected_capability_type)) {
    LOG(WARN) << "Invalid capability setting: " << capability_name
              << " is type " << this->GetJsonTypeDescription(capability_value.type())
              << " instead of " << this->GetJsonTypeDescription(expected_capability_type)
              << ". Default value will be used: " << default_value.toStyledString();
    return default_value;
  }
  return capability_value;
}

bool NewSessionCommandHandler::IsEquivalentType(
    const Json::ValueType& actual_type,
    const Json::ValueType& expected_type) {
  if (expected_type == actual_type) {
    return true;
  }
  if ((expected_type == Json::intValue || expected_type == Json::uintValue || expected_type == Json::realValue) &&
     (actual_type == Json::intValue || actual_type == Json::uintValue || actual_type == Json::realValue)) {
    // All numeric types are equivalent for our purposes.
    return true;
  }
  return false;
}

std::string NewSessionCommandHandler::GetJsonTypeDescription(
    const Json::ValueType& type) {
  switch (type) {
  case Json::booleanValue:
    return "boolean";
  case Json::intValue:
  case Json::uintValue:
  case Json::realValue:
    return "number";
  case Json::objectValue:
    return "object";
  case Json::arrayValue:
    return "array";
  case Json::stringValue:
    return "string";
  }
  return "null";
}

std::string NewSessionCommandHandler::GetUnexpectedAlertBehaviorValue(
    const std::string& desired_value) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::GetUnexpectedAlertBehaviorValue";
  std::string value = DISMISS_AND_NOTIFY_UNEXPECTED_ALERTS;
  if (desired_value == DISMISS_UNEXPECTED_ALERTS ||
      desired_value == ACCEPT_UNEXPECTED_ALERTS ||
      desired_value == ACCEPT_AND_NOTIFY_UNEXPECTED_ALERTS ||
      desired_value == DISMISS_AND_NOTIFY_UNEXPECTED_ALERTS ||
      desired_value == IGNORE_UNEXPECTED_ALERTS) {
    value = desired_value;
  } else {
    LOG(WARN) << "Desired value of " << desired_value << " for "
              << UNHANDLED_PROMPT_BEHAVIOR_CAPABILITY << " is not"
              << " a valid value. Using default of " << value;
  }
  return value;
}

std::string NewSessionCommandHandler::GetPageLoadStrategyValue(
    const std::string& desired_value) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::GetPageLoadStrategyValue";
  std::string value = NORMAL_PAGE_LOAD_STRATEGY;
  if (desired_value == NORMAL_PAGE_LOAD_STRATEGY ||
      desired_value == EAGER_PAGE_LOAD_STRATEGY ||
      desired_value == NONE_PAGE_LOAD_STRATEGY) {
    value = desired_value;
  } else {
    LOG(WARN) << "Desired value of " << desired_value << " for "
              << PAGE_LOAD_STRATEGY_CAPABILITY << " is not"
              << " a valid value. Using default of " << value;
  }
  return value;
}

Json::Value NewSessionCommandHandler::ValidateArguments(const Json::Value& capabilities,
                                                        std::string* error_message) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::ValidateArguments";
  Json::Value validated_capabilities(Json::arrayValue);
  if (!capabilities.isObject()) {
    *error_message = "'capabilities' in new session request body is not a JSON object.";
    return validated_capabilities;
  }
  Json::Value always_match(Json::objectValue);
  if (capabilities.isMember("alwaysMatch")) {
    LOG(DEBUG) << "Found alwaysMatch in capabilities";
    always_match = capabilities["alwaysMatch"];
    if (!always_match.isObject()) {
      *error_message = "alwaysMatch must be a JSON object";
      return validated_capabilities;
    }
  }

  LOG(DEBUG) << "Validating alwaysMatch capability set";
  if (this->ValidateCapabilities(always_match, "alwaysMatch", error_message)) {
    Json::Value empty_capabilities(Json::objectValue);
    Json::Value first_match_candidates(Json::arrayValue);
    first_match_candidates.append(empty_capabilities);
    if (capabilities.isMember("firstMatch")) {
      first_match_candidates = capabilities["firstMatch"];
    }
    if (!first_match_candidates.isArray()) {
      *error_message = "firstMatch must be a JSON list";
      return validated_capabilities;
    } else {
      // If the user passed a "firstMatch" array, but it was empty,
      // seed the firstMatch array with an empty object for merging
      // purposes.
      if (first_match_candidates.size() == 0) {
        first_match_candidates.append(empty_capabilities);
      }
      bool first_match_validation_failure = false;
      Json::Value validated_first_match_candidates(Json::arrayValue);
      for (size_t i = 0; i < first_match_candidates.size(); ++i) {
        LOG(DEBUG) << "Validating firstMatch capability set with index " << i;
        std::string first_match_validation_error = "";
        Json::Value first_match_candidate = first_match_candidates[static_cast<int>(i)];
        if (this->ValidateCapabilities(first_match_candidate,
                                       "firstMatch element " + std::to_string(i),
                                       &first_match_validation_error)) {
          validated_first_match_candidates.append(first_match_candidate);
        } else {
          first_match_validation_failure = true;
          if (error_message->size() == 0) {
            error_message->append("All firstMatch elements failed validation\n");
          } else {
            error_message->append("\n");
          }
          error_message->append(first_match_validation_error);
        }
      }

      if (first_match_validation_failure) {
        return validated_capabilities;
      }

      // Because we seed the list of "firstMatch" values with an empty value
      // if none were passed in, we should always have at least one element
      // in the array of firstMatch candidates. If we don't then every one
      // has failed validation, and we need to return back out.
      if (validated_first_match_candidates.size() > 0) {
        // Reset the error message in the event any of the firstMatch
        // candidates failed validation.
        *error_message = "";

        for (size_t i = 0; i < validated_first_match_candidates.size(); ++i) {
          Json::Value merged_capabilities(Json::objectValue);
          Json::Value first_match = validated_first_match_candidates[static_cast<int>(i)];
          if (!this->MergeCapabilities(always_match,
                                       first_match,
                                       &merged_capabilities,
                                       error_message)) {
            // If any of the capabilities can't be merged, this is a failure
            // condition according to the spec, so we fail here, returning an
            // empty array.
            return Json::Value(Json::arrayValue);
          }
          validated_capabilities.append(merged_capabilities);
        }
      }
    }
  }
  return validated_capabilities;
}

Json::Value NewSessionCommandHandler::ProcessCapabilities(const IECommandExecutor& executor,
                                                          const Json::Value& capabilities,
                                                          std::string* error_message) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::ProcessCapabilities";
  for (size_t i = 0; i < capabilities.size(); ++i) {
    std::string match_error = "";
    Json::Value merged_capabilities = capabilities[static_cast<int>(i)];
    if (this->MatchCapabilities(executor, merged_capabilities, &match_error)) {
      LOG(DEBUG) << "Processing matched capability set with index " << i;
      IECommandExecutor& mutable_executor = const_cast<IECommandExecutor&>(executor);

      Json::Value unexpected_alert_behavior = this->GetCapability(merged_capabilities,
                                                                  UNHANDLED_PROMPT_BEHAVIOR_CAPABILITY,
                                                                  Json::stringValue,
                                                                  Json::Value(Json::stringValue));
      mutable_executor.set_unexpected_alert_behavior(unexpected_alert_behavior.asString());

      Json::Value page_load_strategy = this->GetCapability(merged_capabilities,
                                                           PAGE_LOAD_STRATEGY_CAPABILITY,
                                                           Json::stringValue,
                                                           NORMAL_PAGE_LOAD_STRATEGY);
      mutable_executor.set_page_load_strategy(this->GetPageLoadStrategyValue(page_load_strategy.asString()));

      Json::Value use_strict_file_interactability = this->GetCapability(merged_capabilities,
                                                                        STRICT_FILE_INTERACTABILITY_CAPABILITY,
                                                                        Json::booleanValue,
                                                                        false);
      mutable_executor.set_use_strict_file_interactability(use_strict_file_interactability.asBool());

      Json::Value timeouts = this->GetCapability(merged_capabilities,
                                                 TIMEOUTS_CAPABILITY,
                                                 Json::objectValue,
                                                 Json::Value());
      this->SetTimeoutSettings(executor, timeouts);

      Json::Value ie_options(Json::objectValue);
      if (merged_capabilities.isMember(IE_DRIVER_EXTENSIONS_CAPABILITY)) {
        ie_options = merged_capabilities[IE_DRIVER_EXTENSIONS_CAPABILITY];
      }

      this->SetBrowserFactorySettings(executor, ie_options);

      this->SetInputSettings(executor, ie_options);

      if (merged_capabilities.isMember(PROXY_CAPABILITY)) {
        Json::Value use_per_process_proxy_capability = this->GetCapability(ie_options,
                                                                           USE_PER_PROCESS_PROXY_CAPABILITY,
                                                                           Json::booleanValue,
                                                                           false);
        bool use_per_process_proxy = use_per_process_proxy_capability.asBool();
        this->SetProxySettings(executor,
                               merged_capabilities[PROXY_CAPABILITY],
                               use_per_process_proxy);
      }

      // Use CreateReturnedCapabilities to fill in unspecified capabilities values.
      return this->CreateReturnedCapabilities(executor);
    } else {
      if (error_message->size() == 0) {
        error_message->append("No matching capability sets found.\n");
      } else {
        error_message->append("\n");
      }
      error_message->append("Unable to match capability set ");
      error_message->append(std::to_string(i));
      error_message->append(": ");
      error_message->append(match_error);
    }
  }
  return Json::Value(Json::nullValue);
}

void NewSessionCommandHandler::SetTimeoutSettings(const IECommandExecutor& executor,
                                                  const Json::Value& capabilities) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::SetTimeoutSettings";
  IECommandExecutor& mutable_executor = const_cast<IECommandExecutor&>(executor);
  if (capabilities.isMember(IMPLICIT_WAIT_TIMEOUT_NAME)) {
    mutable_executor.set_implicit_wait_timeout(capabilities[IMPLICIT_WAIT_TIMEOUT_NAME].asUInt64());
  }
  if (capabilities.isMember(PAGE_LOAD_TIMEOUT_NAME)) {
    mutable_executor.set_page_load_timeout(capabilities[PAGE_LOAD_TIMEOUT_NAME].asUInt64());
  }
  if (capabilities.isMember(SCRIPT_TIMEOUT_NAME)) {
    if (capabilities[SCRIPT_TIMEOUT_NAME].isNull()) {
      mutable_executor.set_async_script_timeout(-1);
    } else {
      mutable_executor.set_async_script_timeout(capabilities[SCRIPT_TIMEOUT_NAME].asInt64());
    }
  }
}

void NewSessionCommandHandler::SetBrowserFactorySettings(const IECommandExecutor& executor,
                                                         const Json::Value& capabilities) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::SetBrowserFactorySettings";
  std::string default_initial_url = "http://localhost:" + std::to_string(static_cast<long long>(executor.port())) + "/";
  if (!capabilities.isNull()) {
    BrowserFactorySettings factory_settings;
    Json::Value ignore_protected_mode_settings = this->GetCapability(capabilities,
                                                                     IGNORE_PROTECTED_MODE_CAPABILITY,
                                                                     Json::booleanValue,
                                                                     false);
    factory_settings.ignore_protected_mode_settings = ignore_protected_mode_settings.asBool();

    Json::Value ignore_zoom_setting = this->GetCapability(capabilities,
                                                          IGNORE_ZOOM_SETTING_CAPABILITY,
                                                          Json::booleanValue,
                                                          false);
    factory_settings.ignore_zoom_setting = ignore_zoom_setting.asBool();

    Json::Value browser_attach_timeout = this->GetCapability(capabilities,
                                                             BROWSER_ATTACH_TIMEOUT_CAPABILITY,
                                                             Json::intValue,
                                                             Json::Value(Json::intValue));
    factory_settings.browser_attach_timeout = browser_attach_timeout.asInt();

    Json::Value initial_url = this->GetCapability(capabilities,
                                                  INITIAL_BROWSER_URL_CAPABILITY,
                                                  Json::stringValue, default_initial_url);
    factory_settings.initial_browser_url = initial_url.asString();

    Json::Value force_create_process_api = this->GetCapability(capabilities,
                                                               FORCE_CREATE_PROCESS_API_CAPABILITY,
                                                               Json::booleanValue,
                                                               false);
    factory_settings.force_create_process_api = force_create_process_api.asBool();

    Json::Value force_shell_windows_api = this->GetCapability(capabilities,
                                                              FORCE_SHELL_WINDOWS_API_CAPABILITY,
                                                              Json::booleanValue,
                                                              false);
    factory_settings.force_shell_windows_api = force_shell_windows_api.asBool();

    Json::Value browser_command_line_switches = this->GetCapability(capabilities,
                                                                    BROWSER_COMMAND_LINE_SWITCHES_CAPABILITY,
                                                                    Json::stringValue,
                                                                    Json::Value(Json::stringValue));
    factory_settings.browser_command_line_switches = browser_command_line_switches.asString();

    Json::Value ensure_clean_session = this->GetCapability(capabilities,
                                                           ENSURE_CLEAN_SESSION_CAPABILITY,
                                                           Json::booleanValue,
                                                           false);
    factory_settings.clear_cache_before_launch = ensure_clean_session.asBool();

    // By default, we should not be attaching to edge_ie
    factory_settings.attach_to_edge_ie = false;
    Json::Value attach_to_edgechrome = this->GetCapability(capabilities,
                                                           ATTACH_TO_EDGE_CHROME,
                                                           Json::booleanValue,
                                                           false);
    factory_settings.attach_to_edge_ie = attach_to_edgechrome.asBool();

    // Ignore window handle process id match when launching Edge on IE Mode
    // Useful when the process is launched with admin/privilege rights. This
    // assumes only one Edge browser is running on the host.
    factory_settings.ignore_process_match = false;
    Json::Value ignore_process_match_ie_mode = this->GetCapability(capabilities,
                                                           IGNORE_PROCESS_MATCH,
                                                           Json::booleanValue,
                                                           false);
    factory_settings.ignore_process_match = ignore_process_match_ie_mode.asBool();

    Json::Value edge_executable_path = this->GetCapability(capabilities,
                                                           EDGE_EXECUTABLE_PATH,
                                                           Json::stringValue,
                                                           Json::Value(Json::stringValue));
    factory_settings.edge_executable_path = edge_executable_path.asString();

    IECommandExecutor& mutable_executor = const_cast<IECommandExecutor&>(executor);
    mutable_executor.browser_factory()->Initialize(factory_settings);
    mutable_executor.set_is_edge_mode(factory_settings.attach_to_edge_ie);
    mutable_executor.set_edge_executable_path(factory_settings.edge_executable_path);
  }
}

void NewSessionCommandHandler::SetProxySettings(const IECommandExecutor& executor,
                                                const Json::Value& proxy_capability,
                                                const bool use_per_process_proxy) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::SetProxySettings";
  ProxySettings proxy_settings = { false, "", "", "", "", "", "", "", "", "" };
  if (!proxy_capability.isNull()) {
    // TODO(JimEvans): Validate the members of the proxy JSON object.
    std::string proxy_type = proxy_capability.get("proxyType", "").asString();
    proxy_settings.proxy_type = proxy_type;
    std::string http_proxy = proxy_capability.get("httpProxy", "").asString();
    proxy_settings.http_proxy = http_proxy;
    std::string ftp_proxy = proxy_capability.get("ftpProxy", "").asString();
    proxy_settings.ftp_proxy = ftp_proxy;
    std::string ssl_proxy = proxy_capability.get("sslProxy", "").asString();
    proxy_settings.ssl_proxy = ssl_proxy;
    std::string socks_proxy = proxy_capability.get("socksProxy", "").asString();
    proxy_settings.socks_proxy = socks_proxy;
    if (socks_proxy.length() > 0) {
      // SOCKS proxy user name and password capabilities are ignored if the
      // SOCKS proxy is unset.
      std::string socks_user_name = proxy_capability.get("socksUsername", "").asString();
      proxy_settings.socks_user_name = socks_user_name;
      std::string socks_password = proxy_capability.get("socksPassword", "").asString();
      proxy_settings.socks_password = socks_password;
    }
    std::string autoconfig_url = proxy_capability.get("proxyAutoconfigUrl", "").asString();
    proxy_settings.proxy_autoconfig_url = autoconfig_url;

    Json::Value proxy_bypass_list = proxy_capability.get("noProxy", Json::Value::null);
    if (!proxy_bypass_list.isNull() && proxy_bypass_list.isArray()) {
      std::string no_proxy = "";
      for (size_t i = 0; i < proxy_bypass_list.size(); ++i) {
        if (no_proxy.size() > 0) {
          no_proxy.append(";");
        }
        no_proxy.append(proxy_bypass_list[static_cast<int>(i)].asString());
      }
      proxy_settings.proxy_bypass = no_proxy;
    }

    proxy_settings.use_per_process_proxy = use_per_process_proxy;

    IECommandExecutor& mutable_executor = const_cast<IECommandExecutor&>(executor);
    mutable_executor.proxy_manager()->Initialize(proxy_settings);
  }
}

void NewSessionCommandHandler::SetInputSettings(const IECommandExecutor& executor,
                                                const Json::Value& capabilities) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::SetInputSettings";
  IECommandExecutor& mutable_executor = const_cast<IECommandExecutor&>(executor);
  InputManagerSettings input_manager_settings;
  input_manager_settings.element_repository = mutable_executor.element_manager();

  Json::Value enable_native_events = this->GetCapability(capabilities,
                                                         NATIVE_EVENTS_CAPABILITY,
                                                         Json::booleanValue,
                                                         true);
  input_manager_settings.use_native_events = enable_native_events.asBool();

  Json::Value scroll_behavior = this->GetCapability(capabilities,
                                                    ELEMENT_SCROLL_BEHAVIOR_CAPABILITY,
                                                    Json::intValue,
                                                    Json::Value(Json::intValue));
  input_manager_settings.scroll_behavior = static_cast<ElementScrollBehavior>(scroll_behavior.asInt());

  Json::Value require_window_focus = this->GetCapability(capabilities,
                                                         REQUIRE_WINDOW_FOCUS_CAPABILITY,
                                                         Json::booleanValue,
                                                         false);
  input_manager_settings.require_window_focus = require_window_focus.asBool();

  Json::Value file_upload_dialog_timeout = this->GetCapability(capabilities,
                                                               FILE_UPLOAD_DIALOG_TIMEOUT_CAPABILITY,
                                                               Json::intValue,
                                                               Json::Value(Json::intValue));
  if (file_upload_dialog_timeout.asInt() > 0) {
    mutable_executor.set_file_upload_dialog_timeout(file_upload_dialog_timeout.asInt());
  }

  Json::Value enable_persistent_hover = this->GetCapability(capabilities,
                                                            ENABLE_PERSISTENT_HOVER_CAPABILITY,
                                                            Json::booleanValue,
                                                            true);
  if (require_window_focus.asBool() || !enable_native_events.asBool()) {
    // Setting "require_window_focus" implies SendInput() API, and does not
    // therefore require persistent hover. Likewise, not using native events
    // requires no persistent hover either.
    input_manager_settings.enable_persistent_hover = false;
  } else {
    input_manager_settings.enable_persistent_hover = enable_persistent_hover.asBool();
  }
  mutable_executor.input_manager()->Initialize(input_manager_settings);
}

Json::Value NewSessionCommandHandler::CreateReturnedCapabilities(const IECommandExecutor& executor) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::CreateReturnedCapabilities";
  Json::Value capabilities;
  capabilities[BROWSER_NAME_CAPABILITY] = "internet explorer";
  capabilities[BROWSER_VERSION_CAPABILITY] = std::to_string(static_cast<long long>(executor.browser_factory()->browser_version()));
  capabilities[PLATFORM_NAME_CAPABILITY] = "windows";
  capabilities[ACCEPT_INSECURE_CERTS_CAPABILITY] = false;
  capabilities[PAGE_LOAD_STRATEGY_CAPABILITY] = executor.page_load_strategy();
  capabilities[STRICT_FILE_INTERACTABILITY_CAPABILITY] = executor.use_strict_file_interactability();
  capabilities[SET_WINDOW_RECT_CAPABILITY] = true;

  if (executor.unexpected_alert_behavior().size() > 0) {
    capabilities[UNHANDLED_PROMPT_BEHAVIOR_CAPABILITY] = executor.unexpected_alert_behavior();
  } else {
    capabilities[UNHANDLED_PROMPT_BEHAVIOR_CAPABILITY] = DISMISS_AND_NOTIFY_UNEXPECTED_ALERTS;
  }

  Json::Value timeouts;
  timeouts[IMPLICIT_WAIT_TIMEOUT_NAME] = executor.implicit_wait_timeout();
  timeouts[PAGE_LOAD_TIMEOUT_NAME] = executor.page_load_timeout();
  long long script_timeout = executor.async_script_timeout();
  if (script_timeout < 0) {
    timeouts[SCRIPT_TIMEOUT_NAME] = Json::Value::null;
  } else {
    timeouts[SCRIPT_TIMEOUT_NAME] = script_timeout;
  }
  capabilities[TIMEOUTS_CAPABILITY] = timeouts;

  Json::Value ie_options;
  ie_options[IGNORE_PROTECTED_MODE_CAPABILITY] = executor.browser_factory()->ignore_protected_mode_settings();
  ie_options[IGNORE_ZOOM_SETTING_CAPABILITY] = executor.browser_factory()->ignore_zoom_setting();
  ie_options[INITIAL_BROWSER_URL_CAPABILITY] = executor.browser_factory()->initial_browser_url();
  ie_options[BROWSER_ATTACH_TIMEOUT_CAPABILITY] = executor.browser_factory()->browser_attach_timeout();
  ie_options[BROWSER_COMMAND_LINE_SWITCHES_CAPABILITY] = executor.browser_factory()->browser_command_line_switches();
  ie_options[FORCE_CREATE_PROCESS_API_CAPABILITY] = executor.browser_factory()->force_createprocess_api();
  ie_options[ENSURE_CLEAN_SESSION_CAPABILITY] = executor.browser_factory()->clear_cache();
  ie_options[IGNORE_PROCESS_MATCH] = executor.browser_factory()->ignore_process_match();
  ie_options[NATIVE_EVENTS_CAPABILITY] = executor.input_manager()->enable_native_events();
  ie_options[ENABLE_PERSISTENT_HOVER_CAPABILITY] = executor.input_manager()->use_persistent_hover();
  ie_options[ELEMENT_SCROLL_BEHAVIOR_CAPABILITY] = executor.input_manager()->scroll_behavior();
  ie_options[REQUIRE_WINDOW_FOCUS_CAPABILITY] = executor.input_manager()->require_window_focus();
  ie_options[FILE_UPLOAD_DIALOG_TIMEOUT_CAPABILITY] = executor.file_upload_dialog_timeout();
  ie_options[ATTACH_TO_EDGE_CHROME] = executor.is_edge_mode();
  ie_options[EDGE_EXECUTABLE_PATH] = executor.edge_executable_path();

  if (executor.proxy_manager()->is_proxy_set()) {
    ie_options[USE_PER_PROCESS_PROXY_CAPABILITY] = executor.proxy_manager()->use_per_process_proxy();
    capabilities[PROXY_CAPABILITY] = executor.proxy_manager()->GetProxyAsJson();
  } else {
    capabilities[PROXY_CAPABILITY] = Json::Value(Json::objectValue);
  }

  capabilities[IE_DRIVER_EXTENSIONS_CAPABILITY] = ie_options;
  return capabilities;
}

bool NewSessionCommandHandler::MatchCapabilities(const IECommandExecutor& executor,
                                                 const Json::Value& merged_capabilities,
                                                 std::string* error_message) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::MatchCapabilities";
  std::vector<std::string> capability_names = merged_capabilities.getMemberNames();
  std::vector<std::string>::const_iterator name_iterator = capability_names.begin();
  for (; name_iterator != capability_names.end(); ++name_iterator) {
    std::string capability_name = *name_iterator;
    if (capability_name == BROWSER_NAME_CAPABILITY && 
        merged_capabilities[BROWSER_NAME_CAPABILITY].asString() != "internet explorer") {
      *error_message = "browserName must be 'internet explorer', but was '" +
                       merged_capabilities[BROWSER_NAME_CAPABILITY].asString() +
                       "'";
      return false;
    }

    if (capability_name == PLATFORM_NAME_CAPABILITY &&
        merged_capabilities[PLATFORM_NAME_CAPABILITY].asString() != "windows") {
      *error_message = "platformName must be 'windows', but was '" +
                       merged_capabilities[PLATFORM_NAME_CAPABILITY].asString() +
                       "'";
      return false;
    }

    if (capability_name == BROWSER_VERSION_CAPABILITY) {
      // TODO: Support string version comparisons with '<', '>', '<=', and '>='
      std::string requested_browser_version_value = merged_capabilities[BROWSER_VERSION_CAPABILITY].asString();
      int available_browser_version = executor.browser_factory()->browser_version();
      int requested_browser_version = atoi(requested_browser_version_value.c_str());
      if (available_browser_version != requested_browser_version) {
        *error_message = "requested browserVersion value was '" +
                         requested_browser_version_value +
                         "', but the installed version of IE is " +
                         std::to_string(available_browser_version) +
                         " (note: only exact matches on major version " +
                         "number are supported)";
        return false;
      }
    }

    if (capability_name == ACCEPT_INSECURE_CERTS_CAPABILITY &&
        merged_capabilities[ACCEPT_INSECURE_CERTS_CAPABILITY].asBool()) {
      *error_message = "acceptInsecureCerts was 'true', but the IE driver does not allow bypassing insecure (self-signed) SSL certificates";
      return false;
    }

    if (capability_name.find(":") != std::string::npos &&
        (capability_name != IE_DRIVER_EXTENSIONS_CAPABILITY &&
        capability_name.find("test:") == std::string::npos)) {
      *error_message = capability_name + " is an unknown extension capability for IE";
      return false;
    }
  }

  return true;
}

bool NewSessionCommandHandler::MergeCapabilities(
    const Json::Value& primary_capabilities,
    const Json::Value& secondary_capabilities,
    Json::Value* merged_capabilities,
    std::string* error_message) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::MergeCapabilities";
  std::vector<std::string> primary_property_names = primary_capabilities.getMemberNames();
  for (size_t i = 0; i < primary_property_names.size(); ++i) {
    std::string property_name = primary_property_names[i];
    (*merged_capabilities)[property_name] = primary_capabilities[property_name];
  }

  std::vector<std::string> secondary_property_names = secondary_capabilities.getMemberNames();
  for (size_t i = 0; i < secondary_property_names.size(); ++i) {
    std::string property_name = secondary_property_names[i];
    if (merged_capabilities->isMember(property_name)) {
      *error_message = "Cannot merge capabilities: " +
                       property_name + " is already specified";
      return false;
    }
    (*merged_capabilities)[property_name] = secondary_capabilities[property_name];
  }
  return true;
}

bool NewSessionCommandHandler::ValidateCapabilities(
    const Json::Value& capabilities,
    const std::string& capability_set_name,
    std::string* error_message) {
  LOG(TRACE) << "Entering NewSessionCommandHandler::ValidateCapabilities";
  LOG(DEBUG) << "Validating capabilities object";
  if (!capabilities.isObject() && !capabilities.isNull()) {
    *error_message = capability_set_name + " is not a JSON object.";
    return false;
  }

  if (capabilities.isNull()) {
    return true;
  }

  std::vector<std::string> capability_names = capabilities.getMemberNames();
  std::vector<std::string>::const_iterator name_iterator = capability_names.begin();
  for (; name_iterator != capability_names.end(); ++name_iterator) {
    std::string capability_name = *name_iterator;
    std::string capability_error_message;
    if (capabilities[capability_name].isNull()) {
      // Cast away the const modifier only in this case.
      const_cast<Json::Value&>(capabilities).removeMember(capability_name);
      continue;
    }
    if (capability_name == ACCEPT_INSECURE_CERTS_CAPABILITY) {
      LOG(DEBUG) << "Found " << ACCEPT_INSECURE_CERTS_CAPABILITY << " capability."
                 << " Validating value type is boolean.";
      if (!this->ValidateCapabilityType(capabilities,
                                        capability_name,
                                        Json::ValueType::booleanValue,
                                        &capability_error_message)) {
        *error_message = "Invalid capabilities in " +
                         capability_set_name + ": " + capability_error_message;
        return false;
      }
      continue;
    }

    if (capability_name == STRICT_FILE_INTERACTABILITY_CAPABILITY) {
      LOG(DEBUG) << "Found " << STRICT_FILE_INTERACTABILITY_CAPABILITY << " capability."
        << " Validating value type is boolean.";
      if (!this->ValidateCapabilityType(capabilities,
                                        capability_name,
                                        Json::ValueType::booleanValue,
                                        &capability_error_message)) {
        *error_message = "Invalid capabilities in " +
                         capability_set_name + ": " + capability_error_message;
        return false;
      }
      continue;
    }

    if (capability_name == BROWSER_NAME_CAPABILITY) {
      LOG(DEBUG) << "Found " << BROWSER_NAME_CAPABILITY << " capability."
                 << " Validating value type is string.";
      if (!this->ValidateCapabilityType(capabilities,
                                        capability_name,
                                        Json::ValueType::stringValue,
                                        &capability_error_message)) {
        *error_message = "Invalid capabilities in " +
                         capability_set_name + ": " + capability_error_message;
        return false;
      }
      continue;
    }

    if (capability_name == BROWSER_VERSION_CAPABILITY) {
      LOG(DEBUG) << "Found " << BROWSER_VERSION_CAPABILITY << " capability."
                 << " Validating value type is string.";
      if (!this->ValidateCapabilityType(capabilities,
                                        capability_name,
                                        Json::ValueType::stringValue,
                                        &capability_error_message)) {
        *error_message = "Invalid capabilities in " +
                          capability_set_name + ": " +
                          capability_error_message;
        return false;
      }
      continue;
    }

    if (capability_name == PLATFORM_NAME_CAPABILITY) {
      LOG(DEBUG) << "Found " << PLATFORM_NAME_CAPABILITY << " capability."
                 << " Validating value type is string.";
      if (!this->ValidateCapabilityType(capabilities,
                                        capability_name,
                                        Json::ValueType::stringValue,
                                        &capability_error_message)) {
        *error_message = "Invalid capabilities in " +
                         capability_set_name + ": " + capability_error_message;
        return false;
      }
      continue;
    }

    if (capability_name == UNHANDLED_PROMPT_BEHAVIOR_CAPABILITY) {
      LOG(DEBUG) << "Found " << UNHANDLED_PROMPT_BEHAVIOR_CAPABILITY << " capability."
                 << " Validating value type is string.";
      if (!this->ValidateCapabilityType(capabilities,
                                        capability_name,
                                        Json::ValueType::stringValue,
                                        &capability_error_message)) {
        *error_message = "Invalid capabilities in " +
                         capability_set_name + ": " + capability_error_message;
        return false;
      } else {
        LOG(DEBUG) << "Validating " << UNHANDLED_PROMPT_BEHAVIOR_CAPABILITY << " capability"
                   << " is a valid value.";
        std::string unhandled_prompt_behavior = capabilities[capability_name].asString();
        if (unhandled_prompt_behavior != ACCEPT_UNEXPECTED_ALERTS &&
            unhandled_prompt_behavior != DISMISS_UNEXPECTED_ALERTS &&
            unhandled_prompt_behavior != ACCEPT_AND_NOTIFY_UNEXPECTED_ALERTS &&
            unhandled_prompt_behavior != DISMISS_AND_NOTIFY_UNEXPECTED_ALERTS &&
            unhandled_prompt_behavior != IGNORE_UNEXPECTED_ALERTS) {
          *error_message = "Invalid capabilities in " +
                           capability_set_name + ": " + 
                           "unhandledPromptBehavior is " + 
                           unhandled_prompt_behavior + 
                           " but must be 'accept' or 'dismiss'";
          return false;
        }
      }

      continue;
    }

    if (capability_name == PAGE_LOAD_STRATEGY_CAPABILITY) {
      std::string page_load_strategy = "";
      LOG(DEBUG) << "Found " << PAGE_LOAD_STRATEGY_CAPABILITY << " capability."
                 << " Validating value type is string.";
      if (!this->ValidateCapabilityType(capabilities,
                                        capability_name,
                                        Json::ValueType::stringValue,
                                        &capability_error_message)) {
        *error_message = "Invalid capabilities in " +
                         capability_set_name + ": " + capability_error_message;
        return false;
      } else {
        LOG(DEBUG) << "Validating " << PAGE_LOAD_STRATEGY_CAPABILITY << " capability"
                   << " is a valid value.";
        page_load_strategy = capabilities[capability_name].asString();
        if (page_load_strategy != NONE_PAGE_LOAD_STRATEGY &&
            page_load_strategy != EAGER_PAGE_LOAD_STRATEGY &&
            page_load_strategy != NORMAL_PAGE_LOAD_STRATEGY) {
          *error_message = "Invalid capabilities in " +
                           capability_set_name + ": " +
                           "pageLoadStrategy is " + page_load_strategy +
                           " but must be 'none', 'eager', or 'normal'";
          return false;
        }
      }
      continue;
    }

    if (capability_name == TIMEOUTS_CAPABILITY) {
      LOG(DEBUG) << "Found " << TIMEOUTS_CAPABILITY << " capability."
                 << " Validating value type is object.";
      if (!this->ValidateCapabilityType(capabilities,
                                        capability_name,
                                        Json::ValueType::objectValue,
                                        &capability_error_message)) {
        *error_message = "Invalid capabilities in " +
                         capability_set_name + ": " + capability_error_message;
        return false;
      } else {
        LOG(DEBUG) << "Validating " << TIMEOUTS_CAPABILITY << " capability"
                   << " object contains correct property names.";
        Json::Value timeouts = capabilities[capability_name];
        std::vector<std::string> timeout_names = timeouts.getMemberNames();
        std::vector<std::string>::const_iterator timeout_name_iterator = timeout_names.begin();
        for (; timeout_name_iterator != timeout_names.end(); ++timeout_name_iterator) {
          std::string timeout_name = *timeout_name_iterator;
          if (timeout_name != PAGE_LOAD_TIMEOUT_NAME &&
              timeout_name != IMPLICIT_WAIT_TIMEOUT_NAME &&
              timeout_name != SCRIPT_TIMEOUT_NAME) {
            *error_message = "Invalid capabilities in " +
                             capability_set_name + ": " +
                             "a timeout named " + timeout_name +
                             " is specified, but timeout names must be " +
                             "'implicit', 'pageLoad', or 'script'";
            return false;
          }
          std::string timeout_error = "";
          Json::Value timeout_value = timeouts[timeout_name];
          // Special case: script timeout may be null.
          if (timeout_name != SCRIPT_TIMEOUT_NAME || !timeout_value.isNull()) {
            if (!timeout_value.isNumeric() || !timeout_value.isIntegral()) {
              *error_message = "Invalid capabilities in " +
                               capability_set_name + ": " +
                               "timeout " + timeout_name +
                               "must be an integer";
              return false;
            }
            if (!timeout_value.isInt64()) {
              *error_message = "Invalid capabilities in " +
                               capability_set_name + ": " +
                               "timeout " + timeout_name +
                               "must be an integer between 0 and 2^53 - 1";
              return false;
            }
            long long timeout = timeout_value.asInt64();
            if (timeout < 0 || timeout > MAX_SAFE_INTEGER) {
              *error_message = "Invalid capabilities in " +
                               capability_set_name + ": " +
                               "timeout " + timeout_name +
                               "must be an integer between 0 and 2^53 - 1";
              return false;
            }
          }
        }
      }
      continue;
    }

    if (capability_name == PROXY_CAPABILITY) {
      LOG(DEBUG) << "Found " << PROXY_CAPABILITY << " capability."
                 << " Validating value type is object.";
      if (!this->ValidateCapabilityType(capabilities,
                                        capability_name,
                                        Json::ValueType::objectValue,
                                        &capability_error_message)) {
        *error_message = "Invalid capabilities in " +
                         capability_set_name + ": " +
                         capability_error_message;
        return false;
      } else {
        LOG(DEBUG) << "Validating " << PROXY_CAPABILITY << "capability"
                   << " object structure.";
        Json::Value proxy = capabilities[capability_name];
        std::vector<std::string> proxy_setting_names = proxy.getMemberNames();
        std::vector<std::string>::const_iterator proxy_setting_iterator = proxy_setting_names.begin();
        for (; proxy_setting_iterator != proxy_setting_names.end(); ++proxy_setting_iterator) {
          std::string proxy_error = "";
          std::string proxy_setting = *proxy_setting_iterator;
          if (proxy_setting == "proxyType") {
            if (!this->ValidateCapabilityType(proxy,
                                              proxy_setting,
                                              Json::ValueType::stringValue,
                                              &proxy_error)) {
              *error_message = "Invalid capabilities in " + 
                               capability_set_name + ": " + 
                               "proxy setting " + proxy_error;
              return false;
            }
            std::string proxy_type = proxy[proxy_setting].asString();
            if (proxy_type != "pac" && 
                proxy_type != "direct" && 
                proxy_type != "autodetect" && 
                proxy_type != "system" && 
                proxy_type != "manual") {
              *error_message = "Invalid capabilities in " + 
                               capability_set_name + ": " + 
                               "a proxy type named " + proxy_type + 
                               " is specified, but proxy type must be " +
                               "'pac', 'direct', 'autodetect', 'system', " +
                               "or 'manual'";
              return false;
            }
            continue;
          }

          if (proxy_setting == "proxyAutoconfigUrl" ||
              proxy_setting == "ftpProxy" ||
              proxy_setting == "httpProxy" ||
              proxy_setting == "sslProxy" ||
              proxy_setting == "socksProxy") {
            if (!this->ValidateCapabilityType(proxy, 
                                              proxy_setting,
                                              Json::ValueType::stringValue,
                                              &proxy_error)) {
              *error_message = "Invalid capabilities in " + 
                               capability_set_name + ": " + 
                               "proxy setting " + proxy_error;
              return false;
            }
            continue;
          }

          if (proxy_setting == "noProxy") {
            if (!this->ValidateCapabilityType(proxy,
                                              proxy_setting,
                                              Json::ValueType::arrayValue,
                                              &proxy_error)) {
              *error_message = "Invalid capabilities in " +
                                capability_set_name + ": " +
                                "proxy setting " + proxy_error;
              return false;
            }
            continue;
          }

          if (proxy_setting == "socksVersion") {
            if (!this->ValidateCapabilityType(proxy, proxy_setting,
                                              Json::ValueType::intValue,
                                              &proxy_error)) {
              *error_message = "Invalid capabilities in " + 
                               capability_set_name + ": " + 
                               "proxy setting " + proxy_error;
              return false;
            }
            int socks_version = proxy[proxy_setting].asInt();
            if (socks_version < 0 || socks_version > 255) {
              *error_message = "Invalid capabilities in " +
                                capability_set_name + ": " +
                                "SOCKS version must be between 0 and 255.";
              return false;
            }
            continue;
          }

          *error_message = "Invalid capabilities in " + 
                           capability_set_name + ": " + 
                           "unknown proxy setting named " + proxy_error;
          return false;
        }
      }
      continue;
    }

    if (capability_name == IE_DRIVER_EXTENSIONS_CAPABILITY) {
      LOG(DEBUG) << "Found " << IE_DRIVER_EXTENSIONS_CAPABILITY << " capability."
                 << " Validating value type is object.";
      if (!this->ValidateCapabilityType(capabilities,
                                        capability_name,
                                        Json::ValueType::objectValue,
                                        &capability_error_message)) {
        *error_message = "Invalid capabilities in " + 
                         capability_set_name + ": " +
                         capability_error_message;
        return false;
      }
      continue;
    }

    if (capability_name.find(":") != std::string::npos) {
      LOG(DEBUG) << "Found extension capability named " << capability_name << "."
                 << " Nothing further to validate.";
      continue;
    }

    *error_message = "Invalid capabilities in " + capability_set_name + ": " +
                     "unknown capability named " + capability_name;
    return false;
  }

  return true;
}

bool NewSessionCommandHandler::ValidateCapabilityType(
    const Json::Value& capabilities,
    const std::string& capability_name, 
    const Json::ValueType& expected_capability_type, 
    std::string* error_message) {
  Json::Value capability_value = capabilities[capability_name];
  if (!this->IsEquivalentType(capability_value.type(),
                              expected_capability_type)) {
    *error_message = capability_name + " is type " +
                     this->GetJsonTypeDescription(capability_value.type()) +
                     " instead of " +
                     this->GetJsonTypeDescription(expected_capability_type);
    return false;
  }
  return true;
}

} // namespace webdriver
