package {{packageName}}

{{#operations}}
import (
    "strings"
    "fmt"
    "encoding/json"
    "errors"
    "github.com/dghubble/sling"
{{#imports}}    "{{import}}"
{{/imports}}
)

type {{classname}} struct {
    Configuration Configuration
}

func New{{classname}}() *{{classname}}{
    configuration := NewConfiguration()
    return &{{classname}} {
        Configuration: *configuration,
    }
}

func New{{classname}}WithBasePath(basePath string) *{{classname}}{
    configuration := NewConfiguration()
    configuration.BasePath = basePath
    
    return &{{classname}} {
        Configuration: *configuration,
    }
}

{{#operation}}
/**
 * {{summary}}
 * {{notes}}
{{#allParams}} * @param {{paramName}} {{description}}
{{/allParams}} * @return {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}
 */
func (a {{classname}}) {{nickname}} ({{#allParams}}{{paramName}} {{{dataType}}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) ({{#returnType}}{{{returnType}}}, {{/returnType}}error) {
    {{#allParams}}
    {{#required}}
    // verify the required parameter '{{paramName}}' is set
    if &{{paramName}} == nil {
        return {{#returnType}}*new({{{returnType}}}), {{/returnType}}errors.New("Missing required parameter '{{paramName}}' when calling {{classname}}->{{operationId}}")
    }
    {{/required}}
    {{/allParams}}
    _sling := sling.New().{{httpMethod}}(a.Configuration.BasePath)

    {{#authMethods}}// authentication ({{name}}) required
    {{#isApiKey}}{{#isKeyInHeader}}
    // set key with prefix in header
    _sling.Set("{{keyParamName}}", a.Configuration.GetApiKeyWithPrefix("{{keyParamName}}"))
    {{/isKeyInHeader}}{{#isKeyInQuery}}
    // set key with prefix in querystring
    {{#hasKeyParamName}}    type KeyQueryParams struct {
            {{keyParamName}}    string `url:"{{keyParamName}},omitempty"`
    }
    _sling = _sling.QueryStruct(&KeyQueryParams{ {{keyParamName}}: a.Configuration.GetApiKeyWithPrefix("{{keyParamName}}") })
    {{/hasKeyParamName}}
    {{/isKeyInQuery}}{{/isApiKey}}    
    {{#isBasic}}
    // http basic authentication required
    if a.Configuration.Username != "" || a.Configuration.Password != ""{
        _sling.Set("Authorization",  "Basic " + a.Configuration.GetBasicAuthEncodedString())
    }
    {{/isBasic}}
    {{#isOAuth}}
    // oauth required
    if a.Configuration.AccessToken != ""{
        _sling.Set("Authorization", "Bearer " +  a.Configuration.AccessToken)
    }
    {{/isOAuth}}    
    {{/authMethods}}

    // create path and map variables
    path := "{{basePathWithoutHost}}{{path}}"
{{#pathParams}}    path = strings.Replace(path, "{" + "{{baseName}}" + "}", fmt.Sprintf("%v", {{paramName}}), -1)
{{/pathParams}}

    _sling = _sling.Path(path)

    // add default headers if any
    for key := range a.Configuration.DefaultHeader {
      _sling = _sling.Set(key, a.Configuration.DefaultHeader[key])
    }
    
{{#hasQueryParams}}    type QueryParams struct {
        {{#queryParams}}{{vendorExtensions.x-exportParamName}}    {{dataType}} `url:"{{baseName}},omitempty"`
        {{/queryParams}}
}
    _sling = _sling.QueryStruct(&QueryParams{ {{#queryParams}}{{vendorExtensions.x-exportParamName}}: {{paramName}}{{#hasMore}},{{/hasMore}}{{/queryParams}} })
{{/hasQueryParams}}

    // to determine the Content-Type header
    localVarHttpContentTypes := []string {
        {{#consumes}}
        "{{mediaType}}", 
        {{/consumes}}
    }
    //set Content-Type header
    localVarHttpContentType := a.Configuration.ApiClient.SelectHeaderContentType(localVarHttpContentTypes)
    if localVarHttpContentType != "" {    
      _sling = _sling.Set("Content-Type", localVarHttpContentType)
    }

    // to determine the Accept header
    localVarHttpHeaderAccepts := []string {
        {{#produces}}
        "{{mediaType}}", 
        {{/produces}}
    }
    //set Accept header
    localVarHttpHeaderAccept := a.Configuration.ApiClient.SelectHeaderAccept(localVarHttpHeaderAccepts)
    if localVarHttpHeaderAccept != "" {  
        _sling = _sling.Set("Accept", localVarHttpHeaderAccept)
    }
{{#hasHeaderParams}}{{#headerParams}}    // header params "{{baseName}}"
    _sling = _sling.Set("{{baseName}}", {{paramName}})
{{/headerParams}}{{/hasHeaderParams}}
{{#hasFormParams}}    type FormParams struct {
{{#formParams}}        {{vendorExtensions.x-exportParamName}}    {{dataType}} `url:"{{baseName}},omitempty"`
{{/formParams}}
    }
    _sling = _sling.BodyForm(&FormParams{ {{#formParams}}{{vendorExtensions.x-exportParamName}}: {{paramName}}{{#hasMore}},{{/hasMore}}{{/formParams}} })
{{/hasFormParams}}
{{#hasBodyParam}}{{#bodyParams}}// body params
    _sling = _sling.BodyJSON({{paramName}})
{{/bodyParams}}{{/hasBodyParam}}
{{#returnType}}  var successPayload = new({{returnType}}){{/returnType}}

  // We use this map (below) so that any arbitrary error JSON can be handled.
  // FIXME: This is in the absence of this Go generator honoring the non-2xx
  // response (error) models, which needs to be implemented at some point.
  var failurePayload map[string]interface{}

  httpResponse, err := _sling.Receive({{#returnType}}successPayload{{/returnType}}{{^returnType}}nil{{/returnType}}, &failurePayload)

  if err == nil {
    // err == nil only means that there wasn't a sub-application-layer error (e.g. no network error)
    if failurePayload != nil {
      // If the failurePayload is present, there likely was some kind of non-2xx status
      // returned (and a JSON payload error present)
      var str []byte
      str, err = json.Marshal(failurePayload)
      if err == nil { // For safety, check for an error marshalling... probably superfluous
        // This will return the JSON error body as a string
        err = errors.New(string(str))
      }
  } else {
    // So, there was no network-type error, and nothing in the failure payload,
    // but we should still check the status code
    if httpResponse == nil {
      // This should never happen...
      err = errors.New("No HTTP Response received.")
    } else if code := httpResponse.StatusCode; 200 > code || code > 299 {
        err = errors.New("HTTP Error: " + string(httpResponse.StatusCode))
      }
    }
  }

  return {{#returnType}}*successPayload, {{/returnType}}err
}
{{/operation}}
{{/operations}}
