/**
 * Created by yangm11 on 8/27/2018.
 */
'use strict';

function request(method, url, option) {
  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
      switch (xhr.readyState) {
        case 0:
          // State: UNSENT
          console.log('Client has been created. open() not called yet.');
          return;
        case 1:
          // State: OPENED
          console.log('open() has been called.');
          return;
        case 2:
          // State: HEADERS_RECEIVED
          console.log('send() has been called, and headers and status are' +
              ' available.');
          return;
        case 3:
          // State: LOADING
          // 	Downloading; responseText holds partial data.
          return;
        case 4:
          // State: DONE
          console.log('The operation is complete. But no successful response' +
              ' guaranteed.');

          if (xhr.status >= 500) {
            console.log('Server error!');
            console.log('Status code:', xhr.status);
            console.log('Error message:', xhr.statusText);
            reject({
              ok: false,
              status: xhr.status,
              statusText: xhr.statusText
            });
            return;
          }

          if (xhr.status >= 400) {
            console.log('Client error!');
            console.log('Status code:', xhr.status);
            console.log('Error message:', xhr.statusText);
            reject({
              ok: false,
              status: xhr.status,
              statusText: xhr.statusText
            });
            return;
          }

          if (xhr.status >= 300) {
            console.log('Redirection message received.');
            console.log('Status code', xhr.status);
            console.log('Message:', xhr.statusText);
            return;
          }

          if (xhr.status >= 200) {
            resolve({
              type: xhr.responseType,
              data: xhr.response,
              ok: true,
              status: xhr.status,
              statusText: xhr.statusText
            });
            return;
          }

          if (xhr.status >= 100) {
            console.log('Information responses:', xhr.status);
            return;
          }

          if (xhr.status === 0) {
            reject({
              ok: false,
              status: xhr.status, // browser report a status of 0 in case of
              // XMLHttpRequest errors
              statusText: xhr.statusText
            });
          }
      }
    };
    xhr.open(method, url, true);
    if (option) {
      xhr.send(option);
    } else {
      xhr.send();
    }
  });
}

if (typeof module !== 'undefined' && module.parent) {
  // Node environment, required as module
} else if (typeof window === 'object') {
  // Browser environment
  document.getElementById('url').addEventListener('change', function () {
    let d = request('GET', this.value, null);
    d.then(console.log).catch(err => {
      console.log(err);
    });
  });

} else {
  // Node environment, run directly
  // test code go here
}
@@ -92,16 +92,434 @@
 tion) %7B%0A
+  if (typeof method !== 'string') %7B%0A    throw 'The first argument is expected to be a string.';%0A  %7D%0A  method = method.toUpperCase();%0A  const METHODS = %5B'GET', 'HEAD', 'POST', 'PUT', 'DELETE, OPTIONS, PATCH'%5D;%0A  if (METHODS.indexOf(method) === -1) %7B%0A    throw 'Method not recognized!';%0A  %7D%0A  if (typeof url !== 'string' %7C%7C url.slice(4) !== 'http') %7B%0A    throw 'The second argument is not a valid http url string.';%0A  %7D%0A
   return
@@ -3048,19 +3048,481 @@
  (option
-) %7B
+ && typeof option === 'object') %7B%0A      if (option === null) %7B%0A        xhr.send(null);%0A        return;%0A      %7D%0A      if (option%5B'headers'%5D) %7B%0A        let headers = object.keys(options.headers);%0A        for (let header of headers) %7B%0A          xhr.setRequestHeader(header, option.headers%5Bheader%5D);%0A        %7D%0A        delete option.headers;%0A      %7D%0A%0A      if (option%5B'mimeType'%5D) %7B%0A        xhr.overrideMimeType(option.mimeType);%0A        delete option.mimeType;%0A      %7D%0A
 %0A      x

handle errors