/*jshint -W069 */
"use strict";
(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    return define(['superagent'], factory);
  } else if (typeof module === 'object' && module.exports) {
    // CommonJS-like environments that support module.exports, like Node.
    return module.exports = factory(require(typeof window==="object" ? 'superagent/lib/client' : 'superagent'));
  } else {
    // Browser globals (root is window)
    if (!root.{{{moduleName}}}) {
      root.{{{moduleName}}} = {};
    }
    return root.{{{moduleName}}} = factory(root.superagent);
  }
}(this, function(superagent) {

  function {{{moduleName}}}(options) {
    if (!(this instanceof {{{moduleName}}})) {
      return new {{{moduleName}}}(options);
    }

    this.{{{moduleName}}} = {{{moduleName}}};

    const that = this;
    
    // Requestor definition
    const Requestor = ({{> requestor}})(superagent);
    const requestor = new Requestor();

    this.Requestor = Requestor;
    this.requestor = requestor;

    Object.keys(requestor).concat(Object.keys(Requestor.prototype)).forEach(function (name) {
      if (typeof requestor[name] === 'function') {
        that[name] = function () {
          return requestor[name].apply(requestor, arguments);
        }
      }
    });

    Object.defineProperty(that, 'Promise', {
      get: function () {
        return Requestor.Promise;
      },
      set: function (value) {
        Requestor.Promise = value;
      }
    });

    options && that.configure(options);

    // Models definitions
    const models = {};
    {{#models}}
    models['{{{name}}}'] = ({{> model}})(Requestor, requestor);
    {{/models}}

    // Services definitions
    {{#services}}
    const {{{name}}} = ({{> service}})(requestor);
    {{/services}}

    // Export models
    that.models = models;

    // Export services
    {{#services}}
      that.{{{name}}} = {{{name}}};
    {{/services}}
  }

  return new {{{moduleName}}}();
}));
