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

/**
 * @fileoverview Defines a `webdriver.CommandExecutor` that communicates
 * with a server over HTTP.
 */

goog.provide('webdriver.http.Client');
goog.provide('webdriver.http.Executor');
goog.provide('webdriver.http.Request');
goog.provide('webdriver.http.Response');

goog.require('bot.ErrorCode');
goog.require('goog.array');
goog.require('webdriver.CommandExecutor');
goog.require('webdriver.CommandName');
goog.require('webdriver.logging');



/**
 * Interface used for sending individual HTTP requests to the server.
 * @interface
 */
webdriver.http.Client = function() {
};


/**
 * Sends a request to the server. The client will automatically follow any
 * redirects returned by the server, fulfilling the returned promise with the
 * final response.
 *
 * @param {!webdriver.http.Request} request The request to send.
 * @return {!goog.Promise<!webdriver.http.Response>} A promise that
 *     will be fulfilled with the server's response.
 */
webdriver.http.Client.prototype.send = function(request) {};



/**
 * A command executor that communicates with a server using the WebDriver
 * command protocol.
 * @param {!webdriver.http.Client} client The client to use when sending
 *     requests to the server.
 * @constructor
 * @implements {webdriver.CommandExecutor}
 */
webdriver.http.Executor = function(client) {

  /**
   * Client used to communicate with the server.
   * @private {!webdriver.http.Client}
   */
  this.client_ = client;

  /**
   * @private {!Object<{method:string, path:string}>}
   */
  this.customCommands_ = {};

  /**
   * @private {!webdriver.logging.Logger}
   */
  this.log_ = webdriver.logging.getLogger('webdriver.http.Executor');
};


/**
 * Defines a new command for use with this executor. When a command is sent,
 * the `path` will be preprocessed using the command's parameters; any
 * path segments prefixed with ":" will be replaced by the parameter of the
 * same name. For example, given "/person/:name" and the parameters
 * "{name: 'Bob'}", the final command path will be "/person/Bob".
 *
 * @param {string} name The command name.
 * @param {string} method The HTTP method to use when sending this command.
 * @param {string} path The path to send the command to, relative to
 *     the WebDriver server's command root and of the form
 *     "/path/:variable/segment".
 */
webdriver.http.Executor.prototype.defineCommand = function(
    name, method, path) {
  this.customCommands_[name] = {method: method, path: path};
};


/** @override */
webdriver.http.Executor.prototype.execute = function(command) {
  var resource =
      this.customCommands_[command.getName()] ||
      webdriver.http.Executor.COMMAND_MAP_[command.getName()];
  if (!resource) {
    throw new Error('Unrecognized command: ' + command.getName());
  }

  var parameters = command.getParameters();
  var path = webdriver.http.Executor.buildPath_(resource.path, parameters);
  var request = new webdriver.http.Request(resource.method, path, parameters);

  var log = this.log_;
  log.finer(function() {
    return '>>>\n' + request;
  });

  return this.client_.send(request).then(function(response) {
    log.finer(function() {
      return '<<<\n' + response;
    });
    return webdriver.http.Executor.parseHttpResponse_(
          /** @type {!webdriver.http.Response} */ (response));
  });
};


/**
 * Builds a fully qualified path using the given set of command parameters. Each
 * path segment prefixed with ':' will be replaced by the value of the
 * corresponding parameter. All parameters spliced into the path will be
 * removed from the parameter map.
 * @param {string} path The original resource path.
 * @param {!Object.<*>} parameters The parameters object to splice into
 *     the path.
 * @return {string} The modified path.
 * @private
 */
webdriver.http.Executor.buildPath_ = function(path, parameters) {
  var pathParameters = path.match(/\/:(\w+)\b/g);
  if (pathParameters) {
    for (var i = 0; i < pathParameters.length; ++i) {
      var key = pathParameters[i].substring(2);  // Trim the /:
      if (key in parameters) {
        var value = parameters[key];
        // TODO: move webdriver.WebElement.ELEMENT definition to a
        // common file so we can reference it here without pulling in all of
        // webdriver.WebElement's dependencies.
        if (value && value['ELEMENT']) {
          // When inserting a WebElement into the URL, only use its ID value,
          // not the full JSON.
          value = value['ELEMENT'];
        }
        path = path.replace(pathParameters[i], '/' + value);
        delete parameters[key];
      } else {
        throw new Error('Missing required parameter: ' + key);
      }
    }
  }
  return path;
};


/**
 * Callback used to parse {@link webdriver.http.Response} objects from a
 * {@link webdriver.http.Client}.
 * @param {!webdriver.http.Response} httpResponse The HTTP response to parse.
 * @return {!bot.response.ResponseObject} The parsed response.
 * @private
 */
webdriver.http.Executor.parseHttpResponse_ = function(httpResponse) {
  try {
    return /** @type {!bot.response.ResponseObject} */ (JSON.parse(
        httpResponse.body));
  } catch (ex) {
    // Whoops, looks like the server sent us a malformed response. We'll need
    // to manually build a response object based on the response code.
  }

  var response = {
    'status': bot.ErrorCode.SUCCESS,
    'value': httpResponse.body.replace(/\r\n/g, '\n')
  };

  if (!(httpResponse.status > 199 && httpResponse.status < 300)) {
    // 404 represents an unknown command; anything else is a generic unknown
    // error.
    response['status'] = httpResponse.status == 404 ?
        bot.ErrorCode.UNKNOWN_COMMAND :
        bot.ErrorCode.UNKNOWN_ERROR;
  }

  return response;
};


/**
 * Maps command names to resource locator.
 * @private {!Object.<{method:string, path:string}>}
 * @const
 */
webdriver.http.Executor.COMMAND_MAP_ = (function() {
  return new Builder().
      put(webdriver.CommandName.GET_SERVER_STATUS, get('/status')).
      put(webdriver.CommandName.NEW_SESSION, post('/session')).
      put(webdriver.CommandName.GET_SESSIONS, get('/sessions')).
      put(webdriver.CommandName.DESCRIBE_SESSION, get('/session/:sessionId')).
      put(webdriver.CommandName.QUIT, del('/session/:sessionId')).
      put(webdriver.CommandName.CLOSE, del('/session/:sessionId/window')).
      put(webdriver.CommandName.GET_CURRENT_WINDOW_HANDLE,
          get('/session/:sessionId/window_handle')).
      put(webdriver.CommandName.GET_WINDOW_HANDLES,
          get('/session/:sessionId/window_handles')).
      put(webdriver.CommandName.GET_CURRENT_URL,
          get('/session/:sessionId/url')).
      put(webdriver.CommandName.GET, post('/session/:sessionId/url')).
      put(webdriver.CommandName.GO_BACK, post('/session/:sessionId/back')).
      put(webdriver.CommandName.GO_FORWARD,
          post('/session/:sessionId/forward')).
      put(webdriver.CommandName.REFRESH,
          post('/session/:sessionId/refresh')).
      put(webdriver.CommandName.ADD_COOKIE,
          post('/session/:sessionId/cookie')).
      put(webdriver.CommandName.GET_ALL_COOKIES,
          get('/session/:sessionId/cookie')).
      put(webdriver.CommandName.DELETE_ALL_COOKIES,
          del('/session/:sessionId/cookie')).
      put(webdriver.CommandName.DELETE_COOKIE,
          del('/session/:sessionId/cookie/:name')).
      put(webdriver.CommandName.FIND_ELEMENT,
          post('/session/:sessionId/element')).
      put(webdriver.CommandName.FIND_ELEMENTS,
          post('/session/:sessionId/elements')).
      put(webdriver.CommandName.GET_ACTIVE_ELEMENT,
          post('/session/:sessionId/element/active')).
      put(webdriver.CommandName.FIND_CHILD_ELEMENT,
          post('/session/:sessionId/element/:id/element')).
      put(webdriver.CommandName.FIND_CHILD_ELEMENTS,
          post('/session/:sessionId/element/:id/elements')).
      put(webdriver.CommandName.CLEAR_ELEMENT,
          post('/session/:sessionId/element/:id/clear')).
      put(webdriver.CommandName.CLICK_ELEMENT,
          post('/session/:sessionId/element/:id/click')).
      put(webdriver.CommandName.SEND_KEYS_TO_ELEMENT,
          post('/session/:sessionId/element/:id/value')).
      put(webdriver.CommandName.SUBMIT_ELEMENT,
          post('/session/:sessionId/element/:id/submit')).
      put(webdriver.CommandName.GET_ELEMENT_TEXT,
          get('/session/:sessionId/element/:id/text')).
      put(webdriver.CommandName.GET_ELEMENT_TAG_NAME,
          get('/session/:sessionId/element/:id/name')).
      put(webdriver.CommandName.IS_ELEMENT_SELECTED,
          get('/session/:sessionId/element/:id/selected')).
      put(webdriver.CommandName.IS_ELEMENT_ENABLED,
          get('/session/:sessionId/element/:id/enabled')).
      put(webdriver.CommandName.IS_ELEMENT_DISPLAYED,
          get('/session/:sessionId/element/:id/displayed')).
      put(webdriver.CommandName.GET_ELEMENT_LOCATION,
          get('/session/:sessionId/element/:id/location')).
      put(webdriver.CommandName.GET_ELEMENT_SIZE,
          get('/session/:sessionId/element/:id/size')).
      put(webdriver.CommandName.GET_ELEMENT_ATTRIBUTE,
          get('/session/:sessionId/element/:id/attribute/:name')).
      put(webdriver.CommandName.GET_ELEMENT_VALUE_OF_CSS_PROPERTY,
          get('/session/:sessionId/element/:id/css/:propertyName')).
      put(webdriver.CommandName.ELEMENT_EQUALS,
          get('/session/:sessionId/element/:id/equals/:other')).
      put(webdriver.CommandName.TAKE_ELEMENT_SCREENSHOT,
          get('/session/:sessionId/element/:id/screenshot')).
      put(webdriver.CommandName.SWITCH_TO_WINDOW,
          post('/session/:sessionId/window')).
      put(webdriver.CommandName.MAXIMIZE_WINDOW,
          post('/session/:sessionId/window/:windowHandle/maximize')).
      put(webdriver.CommandName.GET_WINDOW_POSITION,
          get('/session/:sessionId/window/:windowHandle/position')).
      put(webdriver.CommandName.SET_WINDOW_POSITION,
          post('/session/:sessionId/window/:windowHandle/position')).
      put(webdriver.CommandName.GET_WINDOW_SIZE,
          get('/session/:sessionId/window/:windowHandle/size')).
      put(webdriver.CommandName.SET_WINDOW_SIZE,
          post('/session/:sessionId/window/:windowHandle/size')).
      put(webdriver.CommandName.SWITCH_TO_FRAME,
          post('/session/:sessionId/frame')).
      put(webdriver.CommandName.GET_PAGE_SOURCE,
          get('/session/:sessionId/source')).
      put(webdriver.CommandName.GET_TITLE,
          get('/session/:sessionId/title')).
      put(webdriver.CommandName.EXECUTE_SCRIPT,
          post('/session/:sessionId/execute')).
      put(webdriver.CommandName.EXECUTE_ASYNC_SCRIPT,
          post('/session/:sessionId/execute_async')).
      put(webdriver.CommandName.SCREENSHOT,
          get('/session/:sessionId/screenshot')).
      put(webdriver.CommandName.SET_TIMEOUT,
          post('/session/:sessionId/timeouts')).
      put(webdriver.CommandName.SET_SCRIPT_TIMEOUT,
          post('/session/:sessionId/timeouts/async_script')).
      put(webdriver.CommandName.IMPLICITLY_WAIT,
          post('/session/:sessionId/timeouts/implicit_wait')).
      put(webdriver.CommandName.MOVE_TO, post('/session/:sessionId/moveto')).
      put(webdriver.CommandName.CLICK, post('/session/:sessionId/click')).
      put(webdriver.CommandName.DOUBLE_CLICK,
          post('/session/:sessionId/doubleclick')).
      put(webdriver.CommandName.MOUSE_DOWN,
          post('/session/:sessionId/buttondown')).
      put(webdriver.CommandName.MOUSE_UP, post('/session/:sessionId/buttonup')).
      put(webdriver.CommandName.MOVE_TO, post('/session/:sessionId/moveto')).
      put(webdriver.CommandName.SEND_KEYS_TO_ACTIVE_ELEMENT,
          post('/session/:sessionId/keys')).
      put(webdriver.CommandName.TOUCH_SINGLE_TAP,
          post('/session/:sessionId/touch/click')).
      put(webdriver.CommandName.TOUCH_DOUBLE_TAP,
          post('/session/:sessionId/touch/doubleclick')).
      put(webdriver.CommandName.TOUCH_DOWN,
          post('/session/:sessionId/touch/down')).
      put(webdriver.CommandName.TOUCH_UP,
          post('/session/:sessionId/touch/up')).
      put(webdriver.CommandName.TOUCH_MOVE,
          post('/session/:sessionId/touch/move')).
      put(webdriver.CommandName.TOUCH_SCROLL,
          post('/session/:sessionId/touch/scroll')).
      put(webdriver.CommandName.TOUCH_LONG_PRESS,
          post('/session/:sessionId/touch/longclick')).
      put(webdriver.CommandName.TOUCH_FLICK,
          post('/session/:sessionId/touch/flick')).
      put(webdriver.CommandName.ACCEPT_ALERT,
          post('/session/:sessionId/accept_alert')).
      put(webdriver.CommandName.DISMISS_ALERT,
          post('/session/:sessionId/dismiss_alert')).
      put(webdriver.CommandName.GET_ALERT_TEXT,
          get('/session/:sessionId/alert_text')).
      put(webdriver.CommandName.SET_ALERT_TEXT,
          post('/session/:sessionId/alert_text')).
      put(webdriver.CommandName.GET_LOG, post('/session/:sessionId/log')).
      put(webdriver.CommandName.GET_AVAILABLE_LOG_TYPES,
          get('/session/:sessionId/log/types')).
      put(webdriver.CommandName.GET_SESSION_LOGS, post('/logs')).
      put(webdriver.CommandName.UPLOAD_FILE, post('/session/:sessionId/file')).
      build();

  /** @constructor */
  function Builder() {
    var map = {};

    this.put = function(name, resource) {
      map[name] = resource;
      return this;
    };

    this.build = function() {
      return map;
    };
  }

  function post(path) { return resource('POST', path); }
  function del(path)  { return resource('DELETE', path); }
  function get(path)  { return resource('GET', path); }
  function resource(method, path) { return {method: method, path: path}; }
})();


/**
 * Converts a headers object to a HTTP header block string.
 * @param {!Object.<string>} headers The headers object to convert.
 * @return {string} The headers as a string.
 * @private
 */
webdriver.http.headersToString_ = function(headers) {
  var ret = [];
  for (var key in headers) {
    ret.push(key + ': ' + headers[key]);
  }
  return ret.join('\n');
};



/**
 * Describes a partial HTTP request. This class is a "partial" request and only
 * defines the path on the server to send a request to. It is each
 * {@link webdriver.http.Client}'s responsibility to build the full URL for the
 * final request.
 * @param {string} method The HTTP method to use for the request.
 * @param {string} path Path on the server to send the request to.
 * @param {Object=} opt_data This request's JSON data.
 * @constructor
 */
webdriver.http.Request = function(method, path, opt_data) {

  /**
   * The HTTP method to use for the request.
   * @type {string}
   */
  this.method = method;

  /**
   * The path on the server to send the request to.
   * @type {string}
   */
  this.path = path;

  /**
   * This request's body.
   * @type {!Object}
   */
  this.data = opt_data || {};

  /**
   * The headers to send with the request.
   * @type {!Object.<(string|number)>}
   */
  this.headers = {'Accept': 'application/json; charset=utf-8'};
};


/** @override */
webdriver.http.Request.prototype.toString = function() {
  return [
    this.method + ' ' + this.path + ' HTTP/1.1',
    webdriver.http.headersToString_(this.headers),
    '',
    JSON.stringify(this.data)
  ].join('\n');
};



/**
 * Represents a HTTP response.
 * @param {number} status The response code.
 * @param {!Object.<string>} headers The response headers. All header
 *     names will be converted to lowercase strings for consistent lookups.
 * @param {string} body The response body.
 * @constructor
 */
webdriver.http.Response = function(status, headers, body) {

  /**
   * The HTTP response code.
   * @type {number}
   */
  this.status = status;

  /**
   * The response body.
   * @type {string}
   */
  this.body = body;

  /**
   * The response body.
   * @type {!Object.<string>}
   */
  this.headers = {};
  for (var header in headers) {
    this.headers[header.toLowerCase()] = headers[header];
  }
};


/**
 * Builds a {@link webdriver.http.Response} from a {@link XMLHttpRequest} or
 * {@link XDomainRequest} response object.
 * @param {!(XDomainRequest|XMLHttpRequest)} xhr The request to parse.
 * @return {!webdriver.http.Response} The parsed response.
 */
webdriver.http.Response.fromXmlHttpRequest = function(xhr) {
  var headers = {};

  // getAllResponseHeaders is only available on XMLHttpRequest objects.
  if (xhr.getAllResponseHeaders) {
    var tmp = xhr.getAllResponseHeaders();
    if (tmp) {
      tmp = tmp.replace(/\r\n/g, '\n').split('\n');
      goog.array.forEach(tmp, function(header) {
        var parts = header.split(/\s*:\s*/, 2);
        if (parts[0]) {
          headers[parts[0]] = parts[1] || '';
        }
      });
    }
  }

  // If xhr is a XDomainRequest object, it will not have a status.
  // However, if we're parsing the response from a XDomainRequest, then
  // that request must have been a success, so we can assume status == 200.
  var status = xhr.status || 200;
  return new webdriver.http.Response(status, headers,
      xhr.responseText.replace(/\0/g, ''));
};


/** @override */
webdriver.http.Response.prototype.toString = function() {
  var headers = webdriver.http.headersToString_(this.headers);
  var ret = ['HTTP/1.1 ' + this.status, headers];

  if (headers) {
    ret.push('');
  }

  if (this.body) {
    ret.push(this.body);
  }

  return ret.join('\n');
};
