import { Inject, Injectable, Optional } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';

import {
{{#definitions}}
{{#hasEnums}}
{{#enums}}
  {{name}},
{{/enums}}
{{/hasEnums}}
  {{name}}{{^isLast}},{{/isLast}}
{{/definitions}}
} from './models';

{{#enums}}
export enum {{name}} {
  {{#values}}
  {{#upper}}{{value}}{{/upper}} = '{{value}}'{{^isLast}},{{/isLast}}
  {{/values}}
}

{{/enums}}
/**
* Created with angular4-swagger-client-generator.
*/
@Injectable()
export class ApiClientService {

  private domain = '{{&domain}}';

  constructor(private http: HttpClient, @Optional() @Inject('domain') domain: string ) {
    if (domain) {
      this.domain = domain;
    }
  }

{{#methods}}
  /**
  {{#summaryLines}}
  * {{&.}}
  {{/summaryLines}}
  * Method {{&methodName}}
  {{#parameters}}
  {{^isSingleton}}* @param {{&camelCaseName}} {{&description}}{{/isSingleton}}
  {{/parameters}}
  * @return Full HTTP response as Observable
  */
  public {{&methodName}}({{#parameters}}{{&camelCaseName}}: {{typescriptType}}{{^isReqired}} = undefined{{/isReqired}}{{^isLast}}, {{/isLast}}{{/parameters}}): Observable<HttpResponse<{{&response}}>> {
    const uri = `{{&backTickPath}}`;
    {{#hasHeaderParameters}}
    let headers = new HttpHeaders();
    {{/hasHeaderParameters}}
    {{^hasHeaderParameters}}
    const headers = new HttpHeaders();
    {{/hasHeaderParameters}}
    {{#hasQueryParameters}}
    let params = new HttpParams();
    {{/hasQueryParameters}}
    {{^hasQueryParameters}}
    const params = new HttpParams();
    {{/hasQueryParameters}}
    {{#parameters}}
      {{#isQueryParameter}}
        {{#isSingleton}}
    params = params.set('{{&name}}', '{{&singleton}}' + '');
        {{/isSingleton}}
        {{^isSingleton}}
          {{#isPatternType}}
    Object.keys(parameters).forEach(function(parameterName) {
      if (new RegExp('{{&pattern}}').test(parameterName)) {
        params = params.set(parameterName, parameters[parameterName] + '');
      }
    });
          {{/isPatternType}}
          {{^isPatternType}}
    if ({{&camelCaseName}} !== undefined && {{&camelCaseName}} !== null) {
          {{#isArray}}
      {{&camelCaseName}}.forEach((value, index) => {
        if (index === 0) {
          params = params.set('{{&name}}', value + '');
        } else {
          params = params.append('{{&name}}', value + '');
        }
      });
          {{/isArray}}
          {{^isArray}}
      params = params.set('{{&name}}', {{&camelCaseName}} + '');
          {{/isArray}}
    }
          {{/isPatternType}}
        {{/isSingleton}}
      {{/isQueryParameter}}
      {{#isHeaderParameter}}
        {{#isSingleton}}
    headers = headers.set('{{&name}}', '{{&singleton}}' + '');
        {{/isSingleton}}
        {{^isSingleton}}
    if ({{&camelCaseName}} !== undefined && {{&camelCaseName}} !== null) {
          {{#isArray}}
      Object.keys({{&camelCaseName}}).map(value => {
        headers = headers.set('{{&name}}', value + '');
      });
          {{/isArray}}
          {{^isArray}}
      headers = headers.set('{{&name}}', {{&camelCaseName}} + '');
          {{/isArray}}
    }
        {{/isSingleton}}
      {{/isHeaderParameter}}
    {{/parameters}}
    return this.sendRequest<{{&response}}>('{{angular2httpMethod}}', uri, headers, params, {{#hasBodyParameters}}JSON.stringify({{#parameters}}{{#isBodyParameter}}{{&camelCaseName}}{{/isBodyParameter}}{{/parameters}}){{/hasBodyParameters}}{{^hasBodyParameters}}null{{/hasBodyParameters}});
  }

{{/methods}}
  private sendRequest<T>(method: string, uri: string, headers: HttpHeaders, params: HttpParams, body: any): Observable<HttpResponse<T>> {
    if (method === 'get') {
      return this.http.get<T>(this.domain + uri, { headers: headers.set('Accept', 'application/json'), params: params, observe: 'response' });
    } else if (method === 'put') {
      return this.http.put<T>(this.domain + uri, body, { headers: headers.set('Content-Type', 'application/json'), params: params, observe: 'response' });
    } else if (method === 'post') {
      return this.http.post<T>(this.domain + uri, body, { headers: headers.set('Content-Type', 'application/json'), params: params, observe: 'response' });
    } else if (method === 'delete') {
      return this.http.delete<T>(this.domain + uri, { headers: headers, params: params, observe: 'response' });
    } else {
      console.error('Unsupported request: ' + method);
      return Observable.throw('Unsupported request: ' + method);
    }
  }
}
