import superagent from "superagent-es6";

function Api(config) {
  this.config = config;

  var self = this;

  // closure
  var serviceHandler = function (service) {
    return function (data, params, fn) {
      /*
       * - data (object): request data payload
       * - params (object): use to replace the tokens in the url
       * - fn (function): callback to used, with a default which emits 'success' or 'error'
       *   event depending on res.ok value
       *
       * support these different format calls:
       *
       *  - function (data, fn)
       *  - function (data, params, fn)
       */
      // function (data, fn) used
      if ('function' === typeof params && !fn) {
        params = undefined;
        fn = params;
      }
      var req = self.request(service, data, params).end(fn ? fn : function (res) {
        req.emit(res.ok ? "success" : "error", res, data, params);
      });
      return req;
    };
  };
  for (var name in config.services) {
    if (!Object.prototype.hasOwnProperty(this, name)) {
      // syntatic sugar: install a service handler available on
      // the api instance with service name
      self[name] = serviceHandler(name);
    }
  }
}

Api.prototype = {
  paramsPattern: /:([^/]+)/g,

  service: function (id) {
    return this.config.services[id];
  },

  url: function (id) {
    var url = this.config.baseUrl;
    var resource = this.service(id);

    // from time being it"s a simple map
    if (resource) {
      var path;

      if (typeof resource === "string") {
        path = resource;
      }

      if (typeof resource === "object" && resource.path !== undefined) {
        path = resource.path;
      }

      if (!path) {
        throw new Error("path is not defined for route $" + id);
      }

      url += path[0] === "/" ? path : "/" + path;
    }

    return url;
  },

  buildUrl: function (url, params) {
    var tokens = url.match(this.paramsPattern);

    if (!tokens.length) {
      return url;
    }

    for (var i = 0, len = tokens.length; i < len; i += 1) {
      var token = tokens[i];
      var name = token.substring(1);
      if (params[name]) {
        url = url.replace(token, params[name]);
      }
    }
    return url;
  },

  request: function (id, data, params) {
    var service = this.service(id);
    var method = (typeof service === "string" ? "get" : service.method || "get").toLowerCase();
    // fix for delete being a reserved word
    if (method === "delete") {
      method = "del";
    }
    var request = superagent[method];
    if (!request) {
      throw new Error("Invalid method [" + service.method + "]");
    }

    var url = this.url(id);

    if (params) {
      url = this.buildUrl(url, params);
    }

    var _req = request(url, data);
    var header, opts;

    // add global headers
    for (header in this.config.headers) {
      _req.set(header, this.config.headers[header]);
    }

    // add global options to request headers
    for (opts in this.config.options) {
      _req[opts](this.config.options[opts]);
    }

    // add service options to request headers
    for (opts in service.options) {
      _req[opts](service.options[opts]);
    }

    // add service headers
    for (header in service.headers) {
      _req.set(header, service.headers[header]);
    }

    // set credentials
    if (this.config.withCredentials) {
      _req.withCredentials();
    }

    return _req;
  }
};

export default Api;

@@ -39,78 +39,8 @@
 %22;%0A%0A
-function Api(config) %7B%0A  this.config = config;%0A%0A  var self = this;%0A%0A  
 // c
@@ -46,18 +46,16 @@
 closure%0A
-  
 var serv
@@ -84,26 +84,24 @@
 (service) %7B%0A
-  
   return fun
@@ -135,15 +135,11 @@
     
- 
- 
 /*%0A
-  
     
@@ -179,18 +179,16 @@
 payload%0A
-  
      * -
@@ -247,18 +247,16 @@
 rl%0A     
- 
- 
 * - fn (
@@ -337,18 +337,16 @@
 r'%0A     
-  
 *   even
@@ -378,27 +378,23 @@
 ue%0A     
-  
 *%0A     
- 
- 
 * suppor
@@ -430,22 +430,18 @@
 s:%0A     
-  *%0A  
+*%0A
      *  
@@ -467,18 +467,16 @@
 n)%0A     
-  
 *  - fun
@@ -509,15 +509,11 @@
     
-  
 */%0A
-  
     
@@ -540,26 +540,24 @@
 n) used%0A    
-  
 if ('functio
@@ -593,18 +593,16 @@
 %7B%0A      
-  
 params =
@@ -613,18 +613,16 @@
 efined;%0A
-  
       fn
@@ -636,22 +636,18 @@
 ms;%0A    
-  %7D%0A  
+%7D%0A
     var 
@@ -715,26 +715,24 @@
 ion (res) %7B%0A
-  
       req.em
@@ -792,16 +792,12 @@
     
-  
 %7D);%0A
-  
     
@@ -814,17 +814,82 @@
 ;%0A  
-  %7D;%0A  %7D;
+%7D;%0A%7D;%0A%0Afunction Api(config) %7B%0A  this.config = config;%0A%0A  var self = this;%0A
 %0A  f

move closure outside of constructor