// Code generated by go-swagger; DO NOT EDIT.


{{ if .Copyright -}}// {{ comment .Copyright -}}{{ end }}


package {{.Package}}
{{ $package := .Package }}

// This file was generated by the swagger tool.
// Editing this file might prove futile when you re-run the swagger generate command

import (
  "context"
  "fmt"
  "io"
  "net/http"
  "strings"

  "github.com/go-openapi/errors"
  "github.com/go-openapi/loads"
  "github.com/go-openapi/runtime"
  "github.com/go-openapi/runtime/middleware"
  "github.com/go-openapi/runtime/security"
  "github.com/go-openapi/spec"
  "github.com/go-openapi/strfmt"
  "github.com/go-openapi/swag"

  {{ imports .DefaultImports }}
  {{ imports .Imports }}
)

// New{{ pascalize .Name }}API creates a new {{ pascalize .Name }} instance
func New{{ pascalize .Name }}API(spec *loads.Document) *{{ pascalize .Name }}API {
  return &{{ pascalize .Name }}API{
    handlers:               make(map[string]map[string]http.Handler),
    formats:                strfmt.Default,
    defaultConsumes:        "{{ .DefaultConsumes }}",
    defaultProduces:        "{{ .DefaultProduces }}",
    customConsumers:        make(map[string]runtime.Consumer),
    customProducers:        make(map[string]runtime.Producer),
    operationMiddlewares:   make(map[string]middleware.Builder),
    PreServerShutdown:      func() {  },
    ServerShutdown:         func() {  },
    spec:                   spec,
    useSwaggerUI:           false,
    ServeError:             errors.ServeError,
    BasicAuthenticator:     security.BasicAuth,
    APIKeyAuthenticator:    security.APIKeyAuth,
    BearerAuthenticator:    security.BearerAuth,
    {{ range .Consumes }}
      {{- if .Implementation }}
        {{ pascalize .Name }}Consumer: {{ .Implementation }},
      {{- else }}
        {{ pascalize .Name }}Consumer: runtime.ConsumerFunc(func(r io.Reader, target interface{}) error {
          return errors.NotImplemented("{{.Name}} consumer has not yet been implemented")
        }),
      {{- end }}
    {{- end }}
    {{ range .Produces }}
      {{- if .Implementation }}
        {{ pascalize .Name }}Producer: {{ .Implementation }},
      {{- else }}
        {{ pascalize .Name }}Producer: runtime.ProducerFunc(func(w io.Writer, data interface{}) error {
          return errors.NotImplemented("{{.Name}} producer has not yet been implemented")
        }),
      {{- end }}
    {{- end }}
    {{ range .Operations }}
      {{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler:
        {{- if ne .Package $package }}{{ .PackageAlias }}.{{ end }}{{ pascalize .Name }}HandlerFunc(func(params {{ if ne .Package $package }}{{ .PackageAlias }}.{{end }}
    {{- if $.GenOpts.StrictResponders}}
        {{- pascalize .Name }}Params{{if .Authorized}}, principal {{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}{{end}}) {{if ne .Package $package }}{{ .Package }}.{{ end }}{{ pascalize .Name }}Responder {
      return {{if ne .Package $package }}{{ .Package }}.{{ end }}{{ pascalize .Name }}NotImplemented()
    {{else}}
        {{- pascalize .Name }}Params{{if .Authorized}}, principal {{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}{{end}}) middleware.Responder {
      return middleware.NotImplemented("operation {{ if ne .Package $package }}{{ .Package }}.{{ end }}{{pascalize .Name}} has not yet been implemented")
    {{ end -}}
    }),
    {{- end }}
    {{ range .SecurityDefinitions }}
      {{- if .IsBasicAuth }}
      // Applies when the Authorization header is set with the Basic scheme
    {{ pascalize .ID }}Auth: func(user string, pass string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) {
      return nil, errors.NotImplemented("basic auth  ({{ .ID }}) has not yet been implemented")
    },
      {{- end }}
      {{- if .IsAPIKeyAuth }}
      // Applies when the "{{ .Name }}" {{ .Source }} is set
    {{ pascalize .ID }}Auth: func(token string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) {
      return nil, errors.NotImplemented("api key auth ({{ .ID }}) {{.Name}} from {{.Source}} param [{{ .Name }}] has not yet been implemented")
    },
      {{- end }}
      {{- if .IsOAuth2 }}
    {{ pascalize .ID }}Auth: func(token string, scopes []string) ({{if not ( eq .Principal "interface{}" )}}*{{ end }}{{.Principal}}, error) {
      return nil, errors.NotImplemented("oauth2 bearer auth ({{ .ID }}) has not yet been implemented")
    },
      {{- end }}
    {{- end }}
    {{- if .SecurityDefinitions }}
    // default authorizer is authorized meaning no requests are blocked
    APIAuthorizer:    security.Authorized(),
    {{- end }}
  }
}

/*{{ pascalize .Name }}API {{ if .Info }}{{ if .Info.Description }}{{.Info.Description}}{{ else }}the {{ humanize .Name }} API{{ end }}{{ end }} */
type {{ pascalize .Name }}API struct {
  spec            *loads.Document
  context         *middleware.Context
  handlers        map[string]map[string]http.Handler
  formats         strfmt.Registry
  customConsumers map[string]runtime.Consumer
  customProducers map[string]runtime.Producer
  defaultConsumes string
  defaultProduces string
  Middleware      func(middleware.Builder) http.Handler
  useSwaggerUI    bool

  // operationMiddlewares middleware for operations
  operationMiddlewares map[string]middleware.Builder

  // BeforePrepare is called before the Prepare of the operation
  BeforePrepare func(context.Context, string, interface{}) middleware.Responder

  // BasicAuthenticator generates a runtime.Authenticator from the supplied basic auth function.
  // It has a default implementation in the security package, however you can replace it for your particular usage.
  BasicAuthenticator func(security.UserPassAuthentication) runtime.Authenticator
  // APIKeyAuthenticator generates a runtime.Authenticator from the supplied token auth function.
  // It has a default implementation in the security package, however you can replace it for your particular usage.
  APIKeyAuthenticator func(string, string, security.TokenAuthentication) runtime.Authenticator
  // BearerAuthenticator generates a runtime.Authenticator from the supplied bearer token auth function.
  // It has a default implementation in the security package, however you can replace it for your particular usage.
  BearerAuthenticator func(string, security.ScopedTokenAuthentication) runtime.Authenticator
  {{ range .Consumes }}
  // {{ pascalize .Name }}Consumer registers a consumer for the following mime types:
    {{- range .AllSerializers }}
  //   - {{ .MediaType }}
    {{- end }}
    {{ pascalize .Name }}Consumer runtime.Consumer
  {{- end }}
  {{ range .Produces}}
  // {{ pascalize .Name }}Producer registers a producer for the following mime types:
    {{- range .AllSerializers }}
  //   - {{ .MediaType }}
    {{- end }}
    {{ pascalize .Name }}Producer runtime.Producer
  {{- end }}
  {{ range .SecurityDefinitions}}
    {{- if .IsBasicAuth}}

  // {{ pascalize .ID }}Auth registers a function that takes username and password and returns a principal
  // it performs authentication with basic auth
  {{ pascalize .ID }}Auth func(string, string) ({{ if not ( eq .Principal "interface{}" ) }}*{{ end }}{{ .Principal }}, error)
    {{- end }}
    {{- if .IsAPIKeyAuth}}

  // {{ pascalize .ID }}Auth registers a function that takes a token and returns a principal
  // it performs authentication based on an api key {{ .Name }} provided in the {{.Source}}
  {{ pascalize .ID }}Auth func(string) ({{ if not ( eq .Principal "interface{}" ) }}*{{ end }}{{ .Principal }}, error)
    {{- end }}
    {{- if .IsOAuth2 }}

  // {{ pascalize .ID }}Auth registers a function that takes an access token and a collection of required scopes and returns a principal
  // it performs authentication based on an oauth2 bearer token provided in the request
  {{ pascalize .ID }}Auth func(string, []string) ({{ if not ( eq .Principal "interface{}" ) }}*{{ end }}{{ .Principal }}, error)
    {{- end }}
  {{- end }}
  {{- if .SecurityDefinitions }}

  // APIAuthorizer provides access control (ACL/RBAC/ABAC) by providing access to the request and authenticated principal
  APIAuthorizer runtime.Authorizer
  {{- end }}
  {{- $package := .Package }}
  {{ range .Operations }}
    // {{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler sets the operation handler for the {{ humanize .Name }} operation
    {{ if ne  .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler {{ if ne .Package $package }}{{ .PackageAlias }}.{{ end }}{{ pascalize .Name }}Handler
  {{- end }}
  // ServeError is called when an error is received, there is a default handler
  // but you can set your own with this
  ServeError     func(http.ResponseWriter, *http.Request, error)

  // PreServerShutdown is called before the HTTP(S) server is shutdown
  // This allows for custom functions to get executed before the HTTP(S) server stops accepting traffic
  PreServerShutdown func()

  // ServerShutdown is called when the HTTP(S) server is shut down and done
  // handling all active connections and does not accept connections interface{} more
  ServerShutdown func()

  // Custom command line argument groups with their descriptions
  CommandLineOptionsGroups []swag.CommandLineOptionsGroup

  // User defined logger function.
  Logger          func(string, ...interface{})
}

// UseRedoc for documentation at /docs
func ({{.ReceiverName}} *{{ pascalize .Name }}API) UseRedoc() {
	{{.ReceiverName}}.useSwaggerUI = false
}

// UseSwaggerUI for documentation at /docs
func ({{.ReceiverName}} *{{ pascalize .Name }}API) UseSwaggerUI() {
	{{.ReceiverName}}.useSwaggerUI = true
}

// SetDefaultProduces sets the default produces media type
func ({{.ReceiverName}} *{{ pascalize .Name }}API) SetDefaultProduces(mediaType string) {
	{{.ReceiverName}}.defaultProduces = mediaType
}

// SetDefaultConsumes returns the default consumes media type
func ({{.ReceiverName}} *{{ pascalize .Name }}API) SetDefaultConsumes(mediaType string) {
	{{.ReceiverName}}.defaultConsumes = mediaType
}

// SetSpec sets a spec that will be served for the clients.
func ({{.ReceiverName}} *{{ pascalize .Name }}API) SetSpec(spec *loads.Document) {
	{{.ReceiverName}}.spec = spec
}

// DefaultProduces returns the default produces media type
func ({{.ReceiverName}} *{{ pascalize .Name }}API) DefaultProduces() string {
	return {{.ReceiverName}}.defaultProduces
}

// DefaultConsumes returns the default consumes media type
func ({{.ReceiverName}} *{{ pascalize .Name }}API) DefaultConsumes() string {
	return {{.ReceiverName}}.defaultConsumes
}

// Formats returns the registered string formats
func ({{.ReceiverName}} *{{ pascalize .Name }}API) Formats() strfmt.Registry {
	return {{.ReceiverName}}.formats
}

// RegisterFormat registers a custom format validator
func ({{.ReceiverName}} *{{ pascalize .Name }}API) RegisterFormat(name string, format strfmt.Format, validator strfmt.Validator) {
  {{.ReceiverName}}.formats.Add(name, format, validator)
}

// Validate validates the registrations in the {{ pascalize .Name }}API
func ({{.ReceiverName}} *{{ pascalize .Name }}API) Validate() error {
  var unregistered []string
  {{ range .Consumes }}
  if {{.ReceiverName}}.{{ pascalize .Name }}Consumer == nil {
    unregistered = append(unregistered, "{{ pascalize .Name }}Consumer")
  }
  {{- end }}
  {{ range .Produces }}
  if {{.ReceiverName}}.{{ pascalize .Name }}Producer == nil {
    unregistered = append(unregistered, "{{ pascalize .Name }}Producer")
  }
  {{- end }}
  {{ range .SecurityDefinitions }}
  if {{.ReceiverName}}.{{ pascalize .ID }}Auth == nil {
    unregistered = append(unregistered, "{{if .IsAPIKeyAuth }}{{ pascalize .Name }}{{ else }}{{ pascalize .ID }}{{ end }}Auth")
  }
  {{- end }}
  {{ range .Operations }}
  if {{.ReceiverName}}.{{ if ne .Package $package }}{{ pascalize .Package }}{{ end }}{{ pascalize .Name }}Handler == nil {
    unregistered = append(unregistered, "{{ if ne .Package $package }}{{ .Package }}.{{ end }}{{ pascalize .Name }}Handler")
  }
  {{- end }}

  if len(unregistered) > 0 {
    return fmt.Errorf("missing registration: %s", strings.Join(unregistered, ", "))
  }

  return nil
}
// ServeErrorFor gets a error handler for a given operation id
func ({{.ReceiverName}} *{{ pascalize .Name }}API) ServeErrorFor(operationID string) func(http.ResponseWriter, *http.Request, error) {
  return {{.ReceiverName}}.ServeError
}
// AuthenticatorsFor gets the authenticators for the specified security schemes
func ({{.ReceiverName}} *{{ pascalize .Name }}API) AuthenticatorsFor(schemes map[string]spec.SecurityScheme) map[string]runtime.Authenticator {
  {{- if .SecurityDefinitions }}
  result := make(map[string]runtime.Authenticator)
  for name := range schemes {
    switch name {
      {{- range .SecurityDefinitions }}
      case "{{.ID}}":
        {{- if .IsBasicAuth }}
        result[name] = {{.ReceiverName}}.BasicAuthenticator({{ if not ( eq .Principal "interface{}" ) }}func(username, password string) (interface{}, error) {
          return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(username, password)
        }{{ end }})
        {{- end }}
        {{- if .IsAPIKeyAuth }}
        scheme := schemes[name]
          result[name] = {{.ReceiverName}}.APIKeyAuthenticator(scheme.Name, scheme.In, {{ if not ( eq .Principal "interface{}" ) }}func(token string) (interface{}, error) {
          return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(token)
        }{{ end }})
        {{- end }}
        {{- if .IsOAuth2 }}
        result[name] = {{.ReceiverName}}.BearerAuthenticator(name, {{ if not ( eq .Principal "interface{}" ) }}func(token string, scopes []string) (interface{}, error) {
          return {{ end }}{{.ReceiverName}}.{{ pascalize .ID }}Auth{{ if not ( eq .Principal "interface{}" ) }}(token, scopes)
        }{{ end }})
        {{- end }}
      {{end}}
    }
  }
  return result
  {{- else }}
  return nil
  {{- end }}
}

// Authorizer returns the registered authorizer
func ({{.ReceiverName}} *{{ pascalize .Name }}API) Authorizer() runtime.Authorizer {
  {{- if .SecurityDefinitions }}
  return {{.ReceiverName}}.APIAuthorizer
  {{- else }}
  return nil
  {{- end }}
}

// ConsumersFor gets the consumers for the specified media types.
// MIME type parameters are ignored here.
func ({{.ReceiverName}} *{{ pascalize .Name }}API) ConsumersFor(mediaTypes []string) map[string]runtime.Consumer {
  {{- if .Consumes }}
  result := make(map[string]runtime.Consumer, len(mediaTypes))
  for _, mt := range mediaTypes {
    switch mt {
    {{- range .Consumes }}
      {{- range .AllSerializers }}
      case "{{ .MediaType }}":
        result["{{ .MediaType }}"] = {{.ReceiverName}}.{{ pascalize .Name }}Consumer
      {{- end }}
    {{- end }}
    }

    if c, ok := {{.ReceiverName}}.customConsumers[mt]; ok {
      result[mt] = c
    }
  }
  return result
  {{- else }}
  return nil
  {{- end }}
}

// ProducersFor gets the producers for the specified media types.
// MIME type parameters are ignored here.
func ({{.ReceiverName}} *{{ pascalize .Name }}API) ProducersFor(mediaTypes []string) map[string]runtime.Producer {
  {{- if .Produces }}
  result := make(map[string]runtime.Producer, len(mediaTypes))
  for _, mt := range mediaTypes {
    switch mt {
      {{- range .Produces }}
        {{- range .AllSerializers }}
      case "{{ .MediaType }}":
        result["{{ .MediaType }}"] = {{.ReceiverName}}.{{ pascalize .Name }}Producer
        {{- end }}
      {{- end }}
    }

    if p, ok := {{.ReceiverName}}.customProducers[mt]; ok {
      result[mt] = p
    }
  }
  return result
  {{- else }}
  return nil
  {{- end }}
}

// HandlerFor gets a http.Handler for the provided operation method and path
func ({{.ReceiverName}} *{{ pascalize .Name }}API) HandlerFor(method, path string) (http.Handler, bool) {
  if {{.ReceiverName}}.handlers == nil {
    return nil, false
  }
  um := strings.ToUpper(method)
  if _, ok := {{.ReceiverName}}.handlers[um]; !ok {
    return nil, false
  }
  if path == "/" {
    path = ""
  }
  h, ok := {{.ReceiverName}}.handlers[um][path]
  return h, ok
}

// Context returns the middleware context for the {{ humanize .Name }} API
func ({{.ReceiverName}} *{{ pascalize .Name }}API) Context() *middleware.Context {
  if {{.ReceiverName}}.context == nil {
    {{.ReceiverName}}.context = middleware.NewRoutableContext({{.ReceiverName}}.spec, {{.ReceiverName}}, nil)
  }

  return {{ .ReceiverName }}.context
}

func ({{.ReceiverName}} *{{ pascalize .Name }}API) handler(operation string, next http.Handler) http.Handler {
  return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    h := next
    if b, ok := {{.ReceiverName}}.operationMiddlewares[operation]; ok {
      h = b(h)
    }

    h.ServeHTTP(w, r)
  })
}

func ({{.ReceiverName}} *{{ pascalize .Name }}API) initHandlerCache() {
  {{.ReceiverName}}.Context() // don't care about the result, just that the initialization happened
  {{- if .Operations }}
  if {{ .ReceiverName }}.handlers == nil {
    {{.ReceiverName}}.handlers = make(map[string]map[string]http.Handler)
  }
    {{ range .Operations }}
  if {{ .ReceiverName }}.handlers[{{ printf "%q" (upper .Method) }}] == nil {
    {{ .ReceiverName }}.handlers[{{ printf "%q" (upper .Method) }}] = make(map[string]http.Handler)
  }
  {{.ReceiverName}}.handlers[{{ printf "%q" (upper .Method) }}][{{ if eq .Path "/" }}""{{ else }}{{ printf "%q" (cleanPath .Path) }}{{ end }}] = {{ .ReceiverName }}.handler("{{ pascalize .Name }}", {{ if ne .Package $package }}{{ .PackageAlias }}.{{ end }}New{{ pascalize .Name }}({{.ReceiverName}}.context, {{.ReceiverName}}.{{if ne .Package $package}}{{ pascalize .Package }}{{end}}{{ pascalize .Name }}Handler))
    {{- end }}
  {{- end }}
}

// Serve creates a http handler to serve the API over HTTP
// can be used directly in http.ListenAndServe(":8000", api.Serve(nil))
func ({{.ReceiverName}} *{{ pascalize .Name }}API) Serve(builder middleware.Builder) http.Handler {
  {{ .ReceiverName }}.Init()

  if {{ .ReceiverName}}.Middleware != nil {
    return {{ .ReceiverName }}.Middleware(builder)
  }
  if {{.ReceiverName}}.useSwaggerUI {
    return {{.ReceiverName}}.context.APIHandlerSwaggerUI(builder)
  }
  return {{.ReceiverName}}.context.APIHandler(builder)
}

// Init allows you to just initialize the handler cache, you can then recompose the middleware as you see fit
func ({{.ReceiverName}} *{{ pascalize .Name }}API) Init() {
  if len({{.ReceiverName}}.handlers) == 0 {
    {{.ReceiverName}}.initHandlerCache()
  }
}

// RegisterConsumer allows you to add (or override) a consumer for a media type.
func ({{.ReceiverName}} *{{ pascalize .Name }}API) RegisterConsumer(mediaType string, consumer runtime.Consumer) {
  {{.ReceiverName}}.customConsumers[mediaType] = consumer
}

// RegisterProducer allows you to add (or override) a producer for a media type.
func ({{.ReceiverName}} *{{ pascalize .Name }}API) RegisterProducer(mediaType string, producer runtime.Producer) {
  {{.ReceiverName}}.customProducers[mediaType] = producer
}

// AddMiddlewareFor adds a http middleware to existing handler
func ({{.ReceiverName}} *{{ pascalize .Name }}API) AddMiddlewareFor(method, path string, builder middleware.Builder) {
  um := strings.ToUpper(method)
  if path == "/" {
    path = ""
  }
  {{.ReceiverName}}.Init()
  if h, ok := {{.ReceiverName}}.handlers[um][path]; ok {
    {{.ReceiverName}}.handlers[method][path] = builder(h)
  }
}

// RegisterMiddleware allows you to add (or override) a middleware for operation.
func ({{.ReceiverName}} *{{ pascalize .Name }}API) RegisterMiddleware(operation string, builder middleware.Builder) {
  {{.ReceiverName}}.operationMiddlewares[operation] = builder
}
