{{>licenseInfo}}
/* tslint:disable:no-unused-variable member-ordering */

import { Inject, Injectable, Optional }                      from '@angular/core';
{{#useHttpClient}}
import { HttpClient, HttpHeaders, HttpParams,
         HttpResponse, HttpEvent }                           from '@angular/common/http';
import { CustomHttpUrlEncodingCodec }                        from '../encoder';
{{/useHttpClient}}
{{^useHttpClient}}
import { Http, Headers, URLSearchParams }                    from '@angular/http';
import { RequestMethod, RequestOptions, RequestOptionsArgs } from '@angular/http';
import { Response, ResponseContentType }                     from '@angular/http';
import { CustomQueryEncoderHelper }                          from '../encoder';
{{/useHttpClient}}

{{^useRxJS6}}
import { Observable }                                        from 'rxjs/Observable';
{{/useRxJS6}}
{{#useRxJS6}}
import { Observable }                                        from 'rxjs';
{{/useRxJS6}}
{{^useHttpClient}}
import '../rxjs-operators';
{{/useHttpClient}}

{{#imports}}
import { {{classname}} } from '../{{filename}}';
{{/imports}}

import { BASE_PATH, COLLECTION_FORMATS }                     from '../variables';
import { Configuration }                                     from '../configuration';
{{#withInterfaces}}
import { {{classname}}Interface }                            from './{{classFilename}}Interface';
{{/withInterfaces}}

{{#operations}}

{{#description}}
/**
 * {{&description}}
 */
{{/description}}
{{^providedInRoot}}
@Injectable()
{{/providedInRoot}}
{{#providedInRoot}}
@Injectable({
  providedIn: 'root'
})
{{/providedInRoot}}
{{#withInterfaces}}
export class {{classname}} implements {{classname}}Interface {
{{/withInterfaces}}
{{^withInterfaces}}
export class {{classname}} {
{{/withInterfaces}}

    protected basePath = '{{{basePath}}}';
    public defaultHeaders = new {{#useHttpClient}}Http{{/useHttpClient}}Headers();
    public configuration = new Configuration();

    constructor(protected {{#useHttpClient}}httpClient: HttpClient{{/useHttpClient}}{{^useHttpClient}}http: Http{{/useHttpClient}}, @Optional()@Inject(BASE_PATH) basePath: string, @Optional() configuration: Configuration) {
        if (basePath) {
            this.basePath = basePath;
        }
        if (configuration) {
            this.configuration = configuration;
            this.basePath = basePath || configuration.basePath || this.basePath;
        }
    }

    /**
     * @param consumes string[] mime-types
     * @return true: consumes contains 'multipart/form-data', false: otherwise
     */
    private canConsumeForm(consumes: string[]): boolean {
        const form = 'multipart/form-data';
        for (const consume of consumes) {
            if (form === consume) {
                return true;
            }
        }
        return false;
    }

{{^useHttpClient}}
{{! Before HttpClient implementation or method overloading we relied on 2 functions, 1 to return the straight body as json
    and another to get the full response.}}
{{#operation}}
    /**
     * {{&notes}}
     {{#summary}}
     * @summary {{&summary}}
     {{/summary}}
     {{#allParams}}* @param {{paramName}} {{description}}
     {{/allParams}}*/
    {{! if you change this method signature, also change the version below }}
    public {{nickname}}({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{^useHttpClient}}{{#hasParams}}, {{/hasParams}}extraHttpRequestParams?: RequestOptionsArgs{{/useHttpClient}}): Observable<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}{}{{/returnType}}> {
        return this.{{nickname}}WithHttpInfo({{#allParams}}{{paramName}}, {{/allParams}}extraHttpRequestParams)
            .map((response: Response) => {
                if (response.status === 204) {
                    return undefined;
                } else {
{{^isResponseFile}}
                    return response.json() || {};
{{/isResponseFile}}
{{#isResponseFile}}
                    return response.blob();
{{/isResponseFile}}
                }
            });
    }

{{/operation}}
{{/useHttpClient}}

{{#operation}}
    /**
     * {{summary}}
     * {{notes}}
     {{#allParams}}* @param {{paramName}} {{description}}
     {{/allParams}}{{#useHttpClient}}* @param observe set whether or not to return the data Observable as the body, response or events. defaults to returning the body.
     * @param reportProgress flag to report request and response progress.{{/useHttpClient}}
     */
    {{#useHttpClient}}
    public {{nickname}}({{#allParams}}{{^isConstEnumParam}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/isConstEnumParam}}{{/allParams}}observe?: 'body', reportProgress?: boolean): Observable<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>;
    public {{nickname}}({{#allParams}}{{^isConstEnumParam}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/isConstEnumParam}}{{/allParams}}observe?: 'response', reportProgress?: boolean): Observable<HttpResponse<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>>;
    public {{nickname}}({{#allParams}}{{^isConstEnumParam}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/isConstEnumParam}}{{/allParams}}observe?: 'events', reportProgress?: boolean): Observable<HttpEvent<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>>;
    public {{nickname}}({{#allParams}}{{^isConstEnumParam}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/isConstEnumParam}}{{/allParams}}observe: any = 'body', reportProgress: boolean = false ): Observable<any> {
    {{/useHttpClient}}
    {{^useHttpClient}}
    public {{nickname}}WithHttpInfo({{#allParams}}{{paramName}}{{^required}}?{{/required}}: {{{dataType}}}, {{/allParams}}extraHttpRequestParams?: RequestOptionsArgs): Observable<Response> {
    {{/useHttpClient}}
{{#allParams}}

{{#required}}
        {{#isConstEnumParam}}
        let {{paramName}} = {{{dataType}}};
        {{/isConstEnumParam}}
        {{^isConstEnumParam}}
        if ({{paramName}} === null || {{paramName}} === undefined) {
            throw new Error('Required parameter {{paramName}} was null or undefined when calling {{nickname}}.');
        }
        {{/isConstEnumParam}}
{{/required}}
{{/allParams}}

{{#hasQueryParams}}
        {{#useHttpClient}}
        let queryParameters = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
        {{/useHttpClient}}
        {{^useHttpClient}}
        let queryParameters = new URLSearchParams('', new CustomQueryEncoderHelper());
        {{/useHttpClient}}
{{#queryParams}}
        {{#isListContainer}}
        if ({{paramName}}) {
        {{#isCollectionFormatMulti}}
            {{paramName}}.forEach((element) => {
                {{#useHttpClient}}queryParameters = {{/useHttpClient}}queryParameters.append('{{baseName}}', <any>element);
            })
        {{/isCollectionFormatMulti}}
        {{^isCollectionFormatMulti}}
            {{#useHttpClient}}queryParameters = {{/useHttpClient}}queryParameters.set('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS['{{collectionFormat}}']));
        {{/isCollectionFormatMulti}}
        }
        {{/isListContainer}}
        {{^isListContainer}}
        if ({{paramName}} !== undefined && {{paramName}} !== null) {
        {{#isDateTime}}
            {{#useHttpClient}}queryParameters = {{/useHttpClient}}queryParameters.set('{{baseName}}', <any>{{paramName}}.toISOString());
        {{/isDateTime}}
        {{^isDateTime}}
            {{#useHttpClient}}queryParameters = {{/useHttpClient}}queryParameters.set('{{baseName}}', <any>{{paramName}});
        {{/isDateTime}}
        }
        {{/isListContainer}}
{{/queryParams}}

{{/hasQueryParams}}
        let headers = {{#useHttpClient}}this.defaultHeaders;{{/useHttpClient}}{{^useHttpClient}}new Headers(this.defaultHeaders.toJSON()); // https://github.com/angular/angular/issues/6845{{/useHttpClient}}
{{#headerParams}}
        {{#isListContainer}}
        if ({{paramName}}) {
            {{#useHttpClient}}headers = {{/useHttpClient}}headers.set('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS['{{collectionFormat}}']));
        }
        {{/isListContainer}}
        {{^isListContainer}}
        if ({{paramName}} !== undefined && {{paramName}} !== null) {
            {{#useHttpClient}}headers = {{/useHttpClient}}headers.set('{{baseName}}', String({{paramName}}));
        }
        {{/isListContainer}}
{{/headerParams}}

{{#authMethods}}
        // authentication ({{name}}) required
{{#isApiKey}}
{{#isKeyInHeader}}
        if (this.configuration.apiKeys["{{keyParamName}}"]) {
            {{#useHttpClient}}headers = {{/useHttpClient}}headers.set('{{keyParamName}}', this.configuration.apiKeys["{{keyParamName}}"]);
        }

{{/isKeyInHeader}}
{{#isKeyInQuery}}
        if (this.configuration.apiKeys["{{keyParamName}}"]) {
            {{#useHttpClient}}queryParameters = {{/useHttpClient}}queryParameters.set('{{keyParamName}}', this.configuration.apiKeys["{{keyParamName}}"]);
        }

{{/isKeyInQuery}}
{{/isApiKey}}
{{#isBasic}}
        if (this.configuration.username || this.configuration.password) {
            {{#useHttpClient}}headers = {{/useHttpClient}}headers.set('Authorization', 'Basic ' + btoa(this.configuration.username + ':' + this.configuration.password));
        }

{{/isBasic}}
{{#isOAuth}}
        if (this.configuration.accessToken) {
            const accessToken = typeof this.configuration.accessToken === 'function'
                ? this.configuration.accessToken()
                : this.configuration.accessToken;
            {{#useHttpClient}}headers = {{/useHttpClient}}headers.set('Authorization', 'Bearer ' + accessToken);
        }

{{/isOAuth}}
{{/authMethods}}
        // to determine the Accept header
        let httpHeaderAccepts: string[] = [
            {{#produces}}
            '{{{mediaType}}}'{{#hasMore}},{{/hasMore}}
            {{/produces}}
        ];
        const httpHeaderAcceptSelected: string | undefined = this.configuration.selectHeaderAccept(httpHeaderAccepts);
        if (httpHeaderAcceptSelected != undefined) {
{{^useHttpClient}}
            headers.set('Accept', httpHeaderAcceptSelected);
{{/useHttpClient}}
{{#useHttpClient}}
            headers = headers.set('Accept', httpHeaderAcceptSelected);
{{/useHttpClient}}
        }

        // to determine the Content-Type header
        const consumes: string[] = [
            {{#consumes}}
            '{{{mediaType}}}'{{#hasMore}},{{/hasMore}}
            {{/consumes}}
        ];
{{#bodyParam}}
        const httpContentTypeSelected: string | undefined = this.configuration.selectHeaderContentType(consumes);
        if (httpContentTypeSelected != undefined) {
{{^useHttpClient}}
            headers.set('Content-Type', httpContentTypeSelected);
{{/useHttpClient}}
{{#useHttpClient}}
            headers = headers.set('Content-Type', httpContentTypeSelected);
{{/useHttpClient}}
        }
{{/bodyParam}}

{{#hasFormParams}}
        const canConsumeForm = this.canConsumeForm(consumes);

        let formParams: { append(param: string, value: any): void; };
        let useForm = false;
        let convertFormParamsToString = false;
{{#formParams}}
{{#isFile}}
        // use FormData to transmit files using content-type "multipart/form-data"
        // see https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data
        useForm = canConsumeForm;
{{/isFile}}
{{/formParams}}
        if (useForm) {
            formParams = new FormData();
        } else {
{{#useHttpClient}}
            formParams = new HttpParams({encoder: new CustomHttpUrlEncodingCodec()});
{{/useHttpClient}}
{{^useHttpClient}}
            // TODO: this fails if a parameter is a file, the api can't consume "multipart/form-data" and a blob is passed.
            convertFormParamsToString = true;
            formParams = new URLSearchParams('', new CustomQueryEncoderHelper());
            // set the content-type explicitly to avoid having it set to 'text/plain'
            headers.set('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
{{/useHttpClient}}
        }

{{#formParams}}
        {{#isListContainer}}
        if ({{paramName}}) {
        {{#isCollectionFormatMulti}}
            {{paramName}}.forEach((element) => {
                {{#useHttpClient}}formParams = {{/useHttpClient}}formParams.append('{{baseName}}', <any>element){{#useHttpClient}} || formParams{{/useHttpClient}};
            })
        {{/isCollectionFormatMulti}}
        {{^isCollectionFormatMulti}}
            {{#useHttpClient}}formParams = {{/useHttpClient}}formParams.append('{{baseName}}', {{paramName}}.join(COLLECTION_FORMATS['{{collectionFormat}}'])){{#useHttpClient}} || formParams{{/useHttpClient}};
        {{/isCollectionFormatMulti}}
        }
        {{/isListContainer}}
        {{^isListContainer}}
        if ({{paramName}} !== undefined) {
            {{#useHttpClient}}formParams = {{/useHttpClient}}formParams.append('{{baseName}}', <any>{{paramName}}){{#useHttpClient}} || formParams{{/useHttpClient}};
        }
        {{/isListContainer}}
{{/formParams}}

{{/hasFormParams}}
{{#useHttpClient}}
        return this.httpClient.{{httpMethod}}{{^isResponseFile}}<{{#returnType}}{{{returnType}}}{{#isResponseTypeFile}}|undefined{{/isResponseTypeFile}}{{/returnType}}{{^returnType}}any{{/returnType}}>{{/isResponseFile}}(`${this.basePath}{{{path}}}`,{{#isBodyAllowed}}
            {{#bodyParam}}{{paramName}}{{/bodyParam}}{{^bodyParam}}{{#hasFormParams}}convertFormParamsToString ? formParams.toString() : formParams{{/hasFormParams}}{{^hasFormParams}}null{{/hasFormParams}}{{/bodyParam}},{{/isBodyAllowed}}
            {
{{#hasQueryParams}}
                params: queryParameters,
{{/hasQueryParams}}
{{#isResponseFile}}
                responseType: "blob",
{{/isResponseFile}}
                withCredentials: this.configuration.withCredentials,
                headers: headers,
                observe: observe,
                reportProgress: reportProgress
            }
        );
{{/useHttpClient}}
{{^useHttpClient}}
        let requestOptions: RequestOptionsArgs = new RequestOptions({
            method: {{httpMethod}},
            headers: headers,
{{#bodyParam}}
            body: {{paramName}} == null ? '' : JSON.stringify({{paramName}}), // https://github.com/angular/angular/issues/10612
{{/bodyParam}}
{{#hasFormParams}}
            body: convertFormParamsToString ? formParams.toString() : formParams,
{{/hasFormParams}}
{{#isResponseFile}}
            responseType: ResponseContentType.Blob,
{{/isResponseFile}}
{{#hasQueryParams}}
            search: queryParameters,
{{/hasQueryParams}}
            withCredentials:this.configuration.withCredentials
        });
        // https://github.com/swagger-api/swagger-codegen/issues/4037
        if (extraHttpRequestParams) {
            requestOptions = (<any>Object).assign(requestOptions, extraHttpRequestParams);
        }

        return this.http.request(`${this.basePath}{{{path}}}`, requestOptions);
{{/useHttpClient}}
    }

{{/operation}}}
{{/operations}}
