import { ObjectExtensions } from '../Extensions/ObjectExtensions';
import { StringExtensions } from '../Extensions/StringExtensions';
import { IHttpClient } from './IHttpClient';
import { IHttpRequestExecutor } from './IHttpRequestExecutor';
import { HttpRequestExecutor } from './HttpRequestExecutor';

/**
 * Implementation of the xmlHttpclient implementing async promises
 */
export class HttpClient implements IHttpClient {

    private url: string;
    private httpHeaders = new Array();
    private httpRequestExecutor: IHttpRequestExecutor;

    /**
     * Set a value for the HttpHeaders for every request
     * @param key name of the header
     * @param value value of the header
     */
    public setHttpHeader (key: string, value: any): IHttpClient {
        this.httpHeaders[key] = value;
        return this;
    }

    /**
     * Implementation of the xmlHttpclient implementing async promises
     * @param url The url to request to
     * @param httpRequestExecutor (Optional) implementation of @see IHttpRequestExecutor to execute the requests with
     */
    constructor(url: string, httpRequestExecutor: IHttpRequestExecutor = new HttpRequestExecutor()) {
        if (StringExtensions.isNullOrWhitespace(url))
            throw new ReferenceError('The url needs to be defined');
        this.url = url;
        this.httpRequestExecutor = httpRequestExecutor;
    }

    /**
     * Send a HttpGet request to an endpoint
     * @param path Uri extra path parameter
     */
    public httpGetAsync<TModel>(path?: string): Promise<TModel>
    {
        return new Promise<TModel>((resolve, reject) =>
            this.httpRequestExecutor.executeHttpGet(this.constructUrl(path), this.httpHeaders,
                (responseText) => resolve(JSON.parse(responseText)),
                (responseText, statusCode) => reject(`${statusCode}: ${responseText}`)));
    }

    private constructUrl(path: string): string {
        if (StringExtensions.isNullOrWhitespace(path)) return this.url;
        return StringExtensions.trimEndCharacters(this.url, '/') +
        `/${StringExtensions.trimStartCharacters(path, '/')}`;
    }
}

export default HttpClient;