{{>partial_header}}
{{#operations}}
#' @title {{baseName}} operations
#' @description {{importPath}}
#'
#' @field path Stores url path of the request.
#' @field apiClient Handles the client-server communication.
#'
#' @importFrom R6 R6Class
#'
#' @section Methods:
#' \describe{
{{#operation}}
#'
#' {{operationId}} {{summary}}
#'
{{/operation}}
#' }
#'
#' @importFrom caTools base64encode
#' @export
{{classname}} <- R6::R6Class(
  '{{classname}}',
  public = list(
    apiClient = NULL,
    initialize = function(apiClient){
      if (!missing(apiClient)) {
        self$apiClient <- apiClient
      }
      else {
        self$apiClient <- ApiClient$new()
      }
    },
    {{#operation}}
    {{{operationId}}} = function({{#requiredParams}}{{paramName}}, {{/requiredParams}}{{#optionalParams}}{{paramName}}={{^defaultValue}}NULL{{/defaultValue}}{{#defaultValue}}{{{.}}}{{/defaultValue}}, {{/optionalParams}}...){
      args <- list(...)
      queryParams <- list()
      headerParams <- c()

      {{#requiredParams}}
      if (missing(`{{paramName}}`)) {
        stop("Missing required parameter `{{{paramName}}}`.")
      }

      {{/requiredParams}}
      {{#headerParams}}
      headerParams['{{baseName}}'] <- `{{paramName}}`

      {{/headerParams}}
      {{#queryParams}}
      queryParams['{{baseName}}'] <- {{paramName}}

      {{/queryParams}}
      {{#hasFormParams}}
      body <- list(
        {{#formParams}}
        {{^isFile}}
        "{{baseName}}" = {{paramName}}{{#hasMore}},{{/hasMore}}
        {{/isFile}}
        {{#isFile}}
        "{{baseName}}" = httr::upload_file({{paramName}}){{#hasMore}},{{/hasMore}}
        {{/isFile}}
        {{/formParams}}
      )

      {{/hasFormParams}}
      {{#hasBodyParam}}
      {{#bodyParams}}
      if (!missing(`{{paramName}}`)) {
        body <- `{{paramName}}`$toJSONString()
      } else {
        body <- NULL
      }

      {{/bodyParams}}
      {{/hasBodyParam}}
      urlPath <- "{{path}}"
      {{#hasPathParams}}
      {{#pathParams}}
      if (!missing(`{{paramName}}`)) {
        urlPath <- gsub(paste0("\\{", "{{baseName}}", "\\}"), URLencode(as.character(`{{paramName}}`), reserved = TRUE), urlPath)
      }

      {{/pathParams}}
      {{/hasPathParams}}
      {{#authMethods}}
      {{#isBasic}}
      {{#isBasicBasic}}
      # HTTP basic auth
      headerParams['Authorization'] <- paste("Basic", caTools::base64encode(paste(self$apiClient$username, self$apiClient$password, sep=":")), sep=" ")
      {{/isBasicBasic}}
      {{/isBasic}}
      {{#isApiKey}}
      # API key authentication
      {{#isKeyInHeader}}
      if ("{{{keyParamName}}}" %in% names(self$apiClient$apiKeys) && nchar(self$apiClient$apiKeys["{{{keyParamName}}}"]) > 0) {
        headerParams['{{keyParamName}}'] <- paste(unlist(self$apiClient$apiKeys["{{keyParamName}}"]), collapse='')
      }
      {{/isKeyInHeader}}
      {{#isKeyInQuery}}
      if ("{{{keyParamName}}}" %in% names(self$apiClient$apiKeys) && nchar(self$apiClient$apiKeys["{{{keyParamName}}}"]) > 0) {
        queryParams['{{keyParamName}}'] <- paste(unlist(self$apiClient$apiKeys["{{keyParamName}}"]), collapse='')
      }
      {{/isKeyInQuery}}
      {{/isApiKey}}
      {{#isOAuth}}
      # OAuth token
      headerParams['Authorization'] <- paste("Bearer", self$apiClient$accessToken, sep=" ")
      {{/isOAuth}}
      {{/authMethods}}

      resp <- self$apiClient$CallApi(url = paste0(self$apiClient$basePath, urlPath),
                                 method = "{{httpMethod}}",
                                 queryParams = queryParams,
                                 headerParams = headerParams,
                                 body = body,
                                 ...)

      if (httr::status_code(resp) >= 200 && httr::status_code(resp) <= 299) {
        {{#returnType}}
        {{#isPrimitiveType}}
        httr::content(resp, "text", encoding = "UTF-8"
        {{/isPrimitiveType}}
        {{^isPrimitiveType}}
        {{returnType}}$new()$fromJSONString(httr::content(resp, "text", encoding = "UTF-8"))
        {{/isPrimitiveType}}
        {{/returnType}}
        {{^returnType}}
        # void response, no need to return anything
        {{/returnType}}
      } else if (httr::status_code(resp) >= 400 && httr::status_code(resp) <= 499) {
        ApiResponse$new("API client error", resp)
      } else if (httr::status_code(resp) >= 500 && httr::status_code(resp) <= 599) {
        ApiResponse$new("API server error", resp)
      }

    }{{#hasMore}},{{/hasMore}}
    {{/operation}}
  )
)
{{/operations}}
