{% if HasOperations -%}
{% if GenerateClientInterfaces -%}
{% if ExportTypes %}export {% endif %}interface I{{ Class }} {
{%         for operation in Operations -%}
    {% template Client.Method.Documentation %}
    {{ operation.MethodAccessModifier }}{{ operation.ActualOperationName }}({% for parameter in operation.Parameters %}{{ parameter.VariableName }}{% if GenerateOptionalParameters and parameter.IsOptional %}?{% endif %}: {{ parameter.Type }}{{ parameter.TypePostfix }}{% if parameter.IsLast == false %}, {% endif %}{% endfor %}): {{ PromiseType }}<{{ operation.ResultType }}>;
{%         endfor -%}
}
{%- endif -%}

{% if ExportTypes %}export {% endif %}class {{ Class }} {% if HasBaseClass %}extends {{ BaseClass }} {% endif %}{% if GenerateClientInterfaces %}implements I{{ Class }} {% endif %}{
    baseUrl: string;
    beforeSend: any = undefined;
    protected jsonParseReviver: ((key: string, value: any) => any) | undefined = undefined;

{%- if HasExtendedConstructor == false -%}
    constructor({% if HasConfigurationClass %}configuration: {{ ConfigurationClass }}, {% endif %}baseUrl?: string) {
{%-     if HasBaseClass -%}
        super({% if HasConfigurationClass %}configuration{% endif %});
{%-     endif -%}
{%-     if UseGetBaseUrlMethod -%}
        this.baseUrl = baseUrl ?? this.getBaseUrl("{{ BaseUrl }}");
{%-     else -%}
        this.baseUrl = baseUrl ?? "{{ BaseUrl }}";
{%-     endif -%}
    }
{%- endif -%}
{% if HasExtensionCode -%}

    {{ ExtensionCode }}
{%- endif -%}
{% for operation in Operations %}

    {% template Client.Method.Documentation %}
    {{ operation.MethodAccessModifier }}{{ operation.ActualOperationName }}({% for parameter in operation.Parameters %}{{ parameter.VariableName }}{% if GenerateOptionalParameters and parameter.IsOptional %}?{% endif %}: {{ parameter.Type }}{{ parameter.TypePostfix }}{% if parameter.IsLast == false %}, {% endif %}{% endfor %}) {
        return {{ PromiseConstructor }}<{{ operation.ResultType }}>((resolve, reject) => {
            this.{{ operation.ActualOperationName }}WithCallbacks({% for parameter in operation.Parameters %}{{ parameter.VariableName }}, {% endfor %}(result) => resolve(result), (exception, _reason) => reject(exception));
        });
    }

    private {{ operation.ActualOperationName }}WithCallbacks({% for parameter in operation.Parameters %}{{ parameter.VariableName }}: {{ parameter.Type }}{{ parameter.TypePostfix }}, {% endfor %}onSuccess?: (result: {{ operation.ResultType }}) => void, onFail?: (exception: {{ operation.ExceptionType }}, reason: string) => void) {
        {% template Client.RequestUrl %}

{%-    if operation.HasBody -%}
        {% template Client.RequestBody %}

{%-    endif -%}
        jQuery.ajax({% if UseTransformOptionsMethod %}this.transformOptions({% endif %}{
            url: url_,
            beforeSend: this.beforeSend,
            type: "{{ operation.HttpMethodLower }}",
{%-    if operation.HasBody -%}
            data: content_,
{%-    endif -%}
{%-    if operation.HasFormParameters -%}
            mimeType: "multipart/form-data",
            contentType: false,
{%-    else -%}
            dataType: "text",
{%-    endif -%}
            headers: {
{%-    for parameter in operation.HeaderParameters -%}
                "{{ parameter.Name }}": {{ parameter.VariableName }} !== undefined && {{ parameter.VariableName }} !== null ? "" + {{ parameter.VariableName }} : "",
{%     endfor -%}
{%-    if operation.HasContent or operation.ConsumesOnlyFormUrlEncoded -%}
                "Content-Type": "{{ operation.Consumes }}",
{%-    endif -%}
{%-    if operation.HasResultType and operation.HasAcceptHeaderParameterParameter == false -%}
                "Accept": "{{ operation.Produces }}"
{%-    endif -%}
            }
        }{% if UseTransformOptionsMethod -%}
){% endif -%}
).done((_data, _textStatus, xhr) => {
            this.process{{ operation.ActualOperationNameUpper }}WithCallbacks(url_, xhr, onSuccess, onFail);
        }).fail((xhr) => {
            this.process{{ operation.ActualOperationNameUpper }}WithCallbacks(url_, xhr, onSuccess, onFail);
        });
    }

    private process{{ operation.ActualOperationNameUpper }}WithCallbacks(_url: string, xhr: any, onSuccess?: any, onFail?: any): void {
        try {
{%-     if UseTransformResultMethod -%}
            let result = this.transformResult(_url, xhr, (xhr) => this.process{{ operation.ActualOperationNameUpper }}(xhr));
{%-    else -%}
            let result = this.process{{ operation.ActualOperationNameUpper }}(xhr);
{%-    endif -%}
            if (onSuccess !== undefined)
                onSuccess(result);
        } catch (e) {
            if (onFail !== undefined)
                onFail(e, "http_service_exception");
        }
    }

    protected process{{ operation.ActualOperationNameUpper }}(xhr: any): {{ operation.ResultType }} | null {
        const status = xhr.status;

        {% template Client.ProcessResponse %}
    }
{% endfor -%}
}
{%- endif -%}