{{#imports}}
/// <reference path="{{&.}}" />
{{/imports}}

import * as request from "superagent";
import {SuperAgentStatic} from "superagent";

type CallbackHandler = (err: any, res?: request.Response) => void;
{{#definitions}}
type {{&name}} = {{#tsType}}{{> type}}{{/tsType}};
{{/definitions}}

type Logger = { log: (line: string) => any };

/**
 * {{&description}}
 * @class {{&className}}
 * @param {(string)} [domainOrOptions] - The project domain.
 */
export default class {{&className}} {

    private domain: string = "{{&domain}}";
    private errorHandlers: CallbackHandler[] = [];

    constructor(domain?: string, private logger?: Logger) {
        if(domain) {
            this.domain = domain;
        }
    }

    getDomain() {
        return this.domain;
    }

    addErrorHandler(handler: CallbackHandler) {
        this.errorHandlers.push(handler);
    }

    private request(method: string, url: string, body: any, headers: any, queryParameters: any, form: any, reject: CallbackHandler, resolve: CallbackHandler) {
        if(this.logger) {
          this.logger.log(`Call ${method} ${url}`);
        }

        let req = (request as SuperAgentStatic)(method, url).query(queryParameters);

        Object.keys(headers).forEach(key => {
            req.set(key, headers[key]);
        });

        if(body) {
            req.send(body);
        }
        
        if(typeof(body) === 'object' && !(body.constructor.name === 'Buffer')) {
            req.set('Content-Type', 'application/json');
        }

        if(Object.keys(form).length > 0) {
            req.type('form');
            req.send(form);
        }

        req.end((error, response) => {
            if(error || !response.ok) {
                reject(error);
                this.errorHandlers.forEach(handler => handler(error));
            } else {
                resolve(response);
            }
        });
    }

{{#methods}}
    {{> method}}

{{/methods}}
}
