// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of $LIBRARYNAME;

 /**
  * A client-side XHR request for getting data from a URL,
  * formally known as XMLHttpRequest.
  *
  * HttpRequest can be used to obtain data from HTTP and FTP protocols,
  * and is useful for AJAX-style page updates.
  *
  * The simplest way to get the contents of a text file, such as a
  * JSON-formatted file, is with [getString].
  * For example, the following code gets the contents of a JSON file
  * and prints its length:
  *
  *     var path = 'myData.json';
  *     HttpRequest.getString(path)
  *         .then((String fileContents) {
  *           print(fileContents.length);
  *         })
  *         .catchError((Error error) {
  *           print(error.toString());
  *         });
  *
  * ## Fetching data from other servers
  *
  * For security reasons, browsers impose restrictions on requests
  * made by embedded apps.
  * With the default behavior of this class,
  * the code making the request must be served from the same origin
  * (domain name, port, and application layer protocol)
  * as the requested resource.
  * In the example above, the myData.json file must be co-located with the
  * app that uses it.
  * You might be able to
  * [get around this restriction](http://www.dartlang.org/articles/json-web-service/#a-note-on-cors-and-httprequest)
  * by using CORS headers or JSONP.
  *
  * ## Other resources
  *
  * * [Fetch Data Dynamically](https://www.dartlang.org/docs/tutorials/fetchdata/),
  * a tutorial from _A Game of Darts_,
  * shows two different ways to use HttpRequest to get a JSON file.
  * * [Get Input from a Form](https://www.dartlang.org/docs/tutorials/forms/),
  * another tutorial from _A Game of Darts_,
  * shows using HttpRequest with a custom server.
  * * [Dart article on using HttpRequests](http://www.dartlang.org/articles/json-web-service/#getting-data)
  * * [JS XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest)
  * * [Using XMLHttpRequest](https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest)
 */
$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {

  /**
   * Creates a GET request for the specified [url].
   *
   * The server response must be a `text/` mime type for this request to
   * succeed.
   *
   * This is similar to [request] but specialized for HTTP GET requests which
   * return text content.
   *
   * To add query parameters, append them to the [url] following a `?`,
   * joining each key to its value with `=` and separating key-value pairs with
   * `&`.
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.getString('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<String> getString(String url,
      {bool withCredentials, void onProgress(ProgressEvent e)}) {
    return request(url, withCredentials: withCredentials,
        onProgress: onProgress).then((HttpRequest xhr) => xhr.responseText);
  }

  /**
   * Makes a server POST request with the specified data encoded as form data.
   *
   * This is roughly the POST equivalent of getString. This method is similar
   * to sending a FormData object with broader browser support but limited to
   * String values.
   *
   * If [data] is supplied, the key/value pairs are URI encoded with
   * [Uri.encodeQueryComponent] and converted into an HTTP query string.
   *
   * Unless otherwise specified, this method appends the following header:
   *
   *     Content-Type: application/x-www-form-urlencoded; charset=UTF-8
   *
   * Here's an example of using this method:
   *
   *     var data = { 'firstName' : 'John', 'lastName' : 'Doe' };
   *     HttpRequest.postFormData('/send', data).then((HttpRequest resp) {
   *       // Do something with the response.
   *     });
   *
   * See also:
   *
   * * [request]
   */
  static Future<HttpRequest> postFormData(String url, Map<String, String> data,
      {bool withCredentials, String responseType,
      Map<String, String> requestHeaders,
      void onProgress(ProgressEvent e)}) {

    var parts = [];
    data.forEach((key, value) {
      parts.add('${Uri.encodeQueryComponent(key)}='
          '${Uri.encodeQueryComponent(value)}');
    });
    var formData = parts.join('&');

    if (requestHeaders == null) {
      requestHeaders = <String, String>{};
    }
    requestHeaders.putIfAbsent('Content-Type',
        () => 'application/x-www-form-urlencoded; charset=UTF-8');

    return request(url, method: 'POST', withCredentials: withCredentials,
        responseType: responseType,
        requestHeaders: requestHeaders, sendData: formData,
        onProgress: onProgress);
  }

  /**
   * Creates and sends a URL request for the specified [url].
   *
   * By default `request` will perform an HTTP GET request, but a different
   * method (`POST`, `PUT`, `DELETE`, etc) can be used by specifying the
   * [method] parameter. (See also [HttpRequest.postFormData] for `POST` 
   * requests only.
   *
   * The Future is completed when the response is available.
   *
   * If specified, `sendData` will send data in the form of a [ByteBuffer],
   * [Blob], [Document], [String], or [FormData] along with the HttpRequest.
   *
   * If specified, [responseType] sets the desired response format for the
   * request. By default it is [String], but can also be 'arraybuffer', 'blob', 
   * 'document', 'json', or 'text'. See also [HttpRequest.responseType] 
   * for more information.
   *
   * The [withCredentials] parameter specified that credentials such as a cookie
   * (already) set in the header or
   * [authorization headers](http://tools.ietf.org/html/rfc1945#section-10.2)
   * should be specified for the request. Details to keep in mind when using
   * credentials:
   *
   * * Using credentials is only useful for cross-origin requests.
   * * The `Access-Control-Allow-Origin` header of `url` cannot contain a wildcard (*).
   * * The `Access-Control-Allow-Credentials` header of `url` must be set to true.
   * * If `Access-Control-Expose-Headers` has not been set to true, only a subset of all the response headers will be returned when calling [getAllRequestHeaders].
   *
   * The following is equivalent to the [getString] sample above:
   *
   *     var name = Uri.encodeQueryComponent('John');
   *     var id = Uri.encodeQueryComponent('42');
   *     HttpRequest.request('users.json?name=$name&id=$id')
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Here's an example of submitting an entire form with [FormData].
   *
   *     var myForm = querySelector('form#myForm');
   *     var data = new FormData(myForm);
   *     HttpRequest.request('/submit', method: 'POST', sendData: data)
   *       .then((HttpRequest resp) {
   *         // Do something with the response.
   *     });
   *
   * Note that requests for file:// URIs are only supported by Chrome extensions
   * with appropriate permissions in their manifest. Requests to file:// URIs
   * will also never fail- the Future will always complete successfully, even
   * when the file cannot be found.
   *
   * See also: [authorization headers](http://en.wikipedia.org/wiki/Basic_access_authentication).
   */
  static Future<HttpRequest> request(String url,
      {String method, bool withCredentials, String responseType,
      String mimeType, Map<String, String> requestHeaders, sendData,
      void onProgress(ProgressEvent e)}) {
    var completer = new Completer<HttpRequest>();

    var xhr = new HttpRequest();
    if (method == null) {
      method = 'GET';
    }
    xhr.open(method, url, async: true);

    if (withCredentials != null) {
      xhr.withCredentials = withCredentials;
    }

    if (responseType != null) {
      xhr.responseType = responseType;
    }

    if (mimeType != null) {
      xhr.overrideMimeType(mimeType);
    }

    if (requestHeaders != null) {
      requestHeaders.forEach((header, value) {
        xhr.setRequestHeader(header, value);
      });
    }

    if (onProgress != null) {
      xhr.onProgress.listen(onProgress);
    }

    xhr.onLoad.listen((e) {
      // Note: file:// URIs have status of 0.
      if ((xhr.status >= 200 && xhr.status < 300) ||
          xhr.status == 0 || xhr.status == 304) {
        completer.complete(xhr);
      } else {
        completer.completeError(e);
      }
    });

    xhr.onError.listen(completer.completeError);

    if (sendData != null) {
      xhr.send(sendData);
    } else {
      xhr.send();
    }

    return completer.future;
  }

  /**
   * Checks to see if the Progress event is supported on the current platform.
   */
  static bool get supportsProgressEvent {
$if DART2JS
    var xhr = new HttpRequest();
    return JS('bool', '("onprogress" in #)', xhr);
$else
    return true;
$endif
  }

  /**
   * Checks to see if the current platform supports making cross origin
   * requests.
   *
   * Note that even if cross origin requests are supported, they still may fail
   * if the destination server does not support CORS requests.
   */
  static bool get supportsCrossOrigin {
$if DART2JS
    var xhr = new HttpRequest();
    return JS('bool', '("withCredentials" in #)', xhr);
$else
    return true;
$endif
  }

  /**
   * Checks to see if the LoadEnd event is supported on the current platform.
   */
  static bool get supportsLoadEndEvent {
$if DART2JS
    var xhr = new HttpRequest();
    return JS('bool', '("onloadend" in #)', xhr);
$else
    return true;
$endif
  }

  /**
   * Checks to see if the overrideMimeType method is supported on the current
   * platform.
   */
  static bool get supportsOverrideMimeType {
$if DART2JS
    var xhr = new HttpRequest();
    return JS('bool', '("overrideMimeType" in #)', xhr);
$else
    return true;
$endif
  }

  /**
   * Makes a cross-origin request to the specified URL.
   *
   * This API provides a subset of [request] which works on IE9. If IE9
   * cross-origin support is not required then [request] should be used instead.
   */
  @Experimental()
  static Future<String> requestCrossOrigin(String url,
      {String method, String sendData}) {
    if (supportsCrossOrigin) {
      return request(url, method: method, sendData: sendData).then((xhr) {
        return xhr.responseText;
      });
    }
$if DART2JS
    var completer = new Completer<String>();
    if (method == null) {
      method = 'GET';
    }
    var xhr = JS('var', 'new XDomainRequest()');
    JS('', '#.open(#, #)', xhr, method, url);
    JS('', '#.onload = #', xhr, convertDartClosureToJS((e) {
      var response = JS('String', '#.responseText', xhr);
      completer.complete(response);
    }, 1));
    JS('', '#.onerror = #', xhr, convertDartClosureToJS((e) {
      completer.completeError(e);
    }, 1));

    // IE9 RTM - XDomainRequest issued requests may abort if all event handlers
    // not specified
    // http://social.msdn.microsoft.com/Forums/ie/en-US/30ef3add-767c-4436-b8a9-f1ca19b4812e/ie9-rtm-xdomainrequest-issued-requests-may-abort-if-all-event-handlers-not-specified
    JS('', '#.onprogress = {}', xhr);
    JS('', '#.ontimeout = {}', xhr);
    JS('', '#.timeout = Number.MAX_VALUE', xhr);

    if (sendData != null) {
      JS('', '#.send(#)', xhr, sendData);
    } else {
      JS('', '#.send()', xhr);
    }

    return completer.future;
$endif
  }

  /**
   * Returns all response headers as a key-value map.
   *
   * Multiple values for the same header key can be combined into one,
   * separated by a comma and a space.
   *
   * See: http://www.w3.org/TR/XMLHttpRequest/#the-getresponseheader()-method
   */
  Map<String, String> get responseHeaders {
    // from Closure's goog.net.Xhrio.getResponseHeaders.
    var headers = <String, String>{};
    var headersString = this.getAllResponseHeaders();
    if (headersString == null) {
      return headers;
    }
    var headersList = headersString.split('\r\n');
    for (var header in headersList) {
      if (header.isEmpty) {
        continue;
      }

      var splitIdx = header.indexOf(': ');
      if (splitIdx == -1) {
        continue;
      }
      var key = header.substring(0, splitIdx).toLowerCase();
      var value = header.substring(splitIdx + 2);
      if (headers.containsKey(key)) {
        headers[key] = '${headers[key]}, $value';
      } else {
        headers[key] = value;
      }
    }
    return headers;
  }

$!MEMBERS
}
