// Package api provides primitives to interact the openapi HTTP API.
//
// Code generated by github.com/deepmap/oapi-codegen DO NOT EDIT.
package api

import (
	"bytes"
	"compress/gzip"
	"context"
	"encoding/base64"
	"fmt"
	"github.com/deepmap/oapi-codegen/pkg/runtime"
	"github.com/getkin/kin-openapi/openapi3"
	"github.com/go-chi/chi"
	"net/http"
	"strings"
)

type ServerInterface interface {
	// create user (POST /api/v1/user)
	CreateUser(w http.ResponseWriter, r *http.Request)
	// delete user (DELETE /api/v1/user/{userID})
	DeleteUser(w http.ResponseWriter, r *http.Request)
	// get user (GET /api/v1/user/{userID})
	ReadUser(w http.ResponseWriter, r *http.Request)
	// patch user (PATCH /api/v1/user/{userID})
	PatchUser(w http.ResponseWriter, r *http.Request)
}

// CreateUser operation middleware
func CreateUserCtx(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()

		next.ServeHTTP(w, r.WithContext(ctx))
	})
}

// DeleteUser operation middleware
func DeleteUserCtx(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()

		var err error

		// ------------- Path parameter "userID" -------------
		var userID string

		err = runtime.BindStyledParameter("simple", false, "userID", chi.URLParam(r, "userID"), &userID)
		if err != nil {
			http.Error(w, fmt.Sprintf("Invalid format for parameter userID: %s", err), http.StatusBadRequest)
			return
		}

		ctx = context.WithValue(ctx, "userID", userID)

		next.ServeHTTP(w, r.WithContext(ctx))
	})
}

// ReadUser operation middleware
func ReadUserCtx(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()

		var err error

		// ------------- Path parameter "userID" -------------
		var userID string

		err = runtime.BindStyledParameter("simple", false, "userID", chi.URLParam(r, "userID"), &userID)
		if err != nil {
			http.Error(w, fmt.Sprintf("Invalid format for parameter userID: %s", err), http.StatusBadRequest)
			return
		}

		ctx = context.WithValue(ctx, "userID", userID)

		next.ServeHTTP(w, r.WithContext(ctx))
	})
}

// PatchUser operation middleware
func PatchUserCtx(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		ctx := r.Context()

		var err error

		// ------------- Path parameter "userID" -------------
		var userID string

		err = runtime.BindStyledParameter("simple", false, "userID", chi.URLParam(r, "userID"), &userID)
		if err != nil {
			http.Error(w, fmt.Sprintf("Invalid format for parameter userID: %s", err), http.StatusBadRequest)
			return
		}

		ctx = context.WithValue(ctx, "userID", userID)

		next.ServeHTTP(w, r.WithContext(ctx))
	})
}

// Handler creates http.Handler with routing matching OpenAPI spec.
func Handler(si ServerInterface) http.Handler {
	return HandlerFromMux(si, chi.NewRouter())
}

// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux.
func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler {
	r.Group(func(r chi.Router) {
		r.Use(CreateUserCtx)
		r.Post("/api/v1/user", si.CreateUser)
	})
	r.Group(func(r chi.Router) {
		r.Use(DeleteUserCtx)
		r.Delete("/api/v1/user/{userID}", si.DeleteUser)
	})
	r.Group(func(r chi.Router) {
		r.Use(ReadUserCtx)
		r.Get("/api/v1/user/{userID}", si.ReadUser)
	})
	r.Group(func(r chi.Router) {
		r.Use(PatchUserCtx)
		r.Patch("/api/v1/user/{userID}", si.PatchUser)
	})

	return r
}

// Base64 encoded, gzipped, json marshaled Swagger object
var swaggerSpec = []string{

	"H4sIAAAAAAAC/+xUTY/TMBD9K2jgGDUtIA4+wu6hQgi0Yk9ohYwzTb1KbDOeVKqq/Hc0k2SpNi3isIIe",
	"9tLYz/P53nQO4GKbYsDAGcwBsttia/V4TXSDOcWQUa6JYkJij/rY5lo+vE8IBjKTDzX0BRD+7DDzd1+d",
	"eO6LCYk/7tGxOOxWi9uMNM8wRNhEai2DAR/43Vt4COADY40kEbqMdDrf+BZsi39VjUA+bKIYN97h2Png",
	"D5/WXyUke27kKqGhgB1S9jGAgdViuViKRUwYbPJg4I1CBSTLW22qtMmXu1XZTS3HzPKVxi37GNYVGPhA",
	"aBlvhwQjo+9jtRdLFwNjUCebUuOdupX3WWqY9JPTK8INGHhZ/ha4HNUtJ9K1Y0ngCSswTB0qMKiuFb9e",
	"Lp8s7fFEaeoKsyOfeCDw80dQbGO7hv9V0muiSDoMuWtbS3sw4JT/F6PCbOsM5hsoY3dieaxieZDf9VUv",
	"dVTYIONc0CvFHwSd03uhRAz9nCGigBpPDO8N2uoPnT79/F4odzXyWeKSJdsiIwl8AC8xZEdAMS2bYajg",
	"8b+zOKr38Tq70z3jtnNJvgj8vE7+1ySoKue2Sd//CgAA///HPVDsgwcAAA==",
}

// GetSwagger returns the Swagger specification corresponding to the generated code
// in this file.
func GetSwagger() (*openapi3.Swagger, error) {
	zipped, err := base64.StdEncoding.DecodeString(strings.Join(swaggerSpec, ""))
	if err != nil {
		return nil, fmt.Errorf("error base64 decoding spec: %s", err)
	}
	zr, err := gzip.NewReader(bytes.NewReader(zipped))
	if err != nil {
		return nil, fmt.Errorf("error decompressing spec: %s", err)
	}
	var buf bytes.Buffer
	_, err = buf.ReadFrom(zr)
	if err != nil {
		return nil, fmt.Errorf("error decompressing spec: %s", err)
	}

	swagger, err := openapi3.NewSwaggerLoader().LoadSwaggerFromData(buf.Bytes())
	if err != nil {
		return nil, fmt.Errorf("error loading Swagger: %s", err)
	}
	return swagger, nil
}
