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

package restapi

import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/go-openapi/errors"
	"github.com/go-openapi/loads"
	"github.com/go-openapi/runtime"
	"github.com/go-openapi/runtime/middleware"

	"github.com/Cyclops-Labs/cyclops-4-hpc.git/services/customerdb/restapi/operations"
	"github.com/Cyclops-Labs/cyclops-4-hpc.git/services/customerdb/restapi/operations/customer_management"
	"github.com/Cyclops-Labs/cyclops-4-hpc.git/services/customerdb/restapi/operations/product_management"
	"github.com/Cyclops-Labs/cyclops-4-hpc.git/services/customerdb/restapi/operations/reseller_management"
	"github.com/Cyclops-Labs/cyclops-4-hpc.git/services/customerdb/restapi/operations/status_management"
	"github.com/Cyclops-Labs/cyclops-4-hpc.git/services/customerdb/restapi/operations/trigger_management"
)

type contextKey string

const AuthKey contextKey = "Auth"

//go:generate mockery -name CustomerManagementAPI -inpkg

/* CustomerManagementAPI  */
type CustomerManagementAPI interface {
	/* AddCustomer Insert a new customer in the system. */
	AddCustomer(ctx context.Context, params customer_management.AddCustomerParams) middleware.Responder

	/* GetCustomer Return the information about the customer with the given id */
	GetCustomer(ctx context.Context, params customer_management.GetCustomerParams) middleware.Responder

	/* ListCustomers List all the customers in the system */
	ListCustomers(ctx context.Context, params customer_management.ListCustomersParams) middleware.Responder

	/* UpdateCustomer Updates the information of the customer with the given id */
	UpdateCustomer(ctx context.Context, params customer_management.UpdateCustomerParams) middleware.Responder
}

//go:generate mockery -name ProductManagementAPI -inpkg

/* ProductManagementAPI  */
type ProductManagementAPI interface {
	/* AddProduct Insert a new product in the system. */
	AddProduct(ctx context.Context, params product_management.AddProductParams) middleware.Responder

	/* GetProduct Return the information about the product with the given id */
	GetProduct(ctx context.Context, params product_management.GetProductParams) middleware.Responder

	/* ListProducts List all the products in the system */
	ListProducts(ctx context.Context, params product_management.ListProductsParams) middleware.Responder

	/* UpdateProduct Updates the information of the product with the given id */
	UpdateProduct(ctx context.Context, params product_management.UpdateProductParams) middleware.Responder
}

//go:generate mockery -name ResellerManagementAPI -inpkg

/* ResellerManagementAPI  */
type ResellerManagementAPI interface {
	/* AddReseller Insert a new reseller in the system. */
	AddReseller(ctx context.Context, params reseller_management.AddResellerParams) middleware.Responder

	/* GetReseller Return the information about the reseller with the given id */
	GetReseller(ctx context.Context, params reseller_management.GetResellerParams) middleware.Responder

	/* ListResellers List all the resellers in the system */
	ListResellers(ctx context.Context, params reseller_management.ListResellersParams) middleware.Responder

	/* UpdateReseller Updates the information of the reseller with the given id */
	UpdateReseller(ctx context.Context, params reseller_management.UpdateResellerParams) middleware.Responder
}

//go:generate mockery -name StatusManagementAPI -inpkg

/* StatusManagementAPI  */
type StatusManagementAPI interface {
	/* GetStatus Basic status of the system */
	GetStatus(ctx context.Context, params status_management.GetStatusParams) middleware.Responder

	/* ShowStatus Basic status of the system */
	ShowStatus(ctx context.Context, params status_management.ShowStatusParams) middleware.Responder
}

//go:generate mockery -name TriggerManagementAPI -inpkg

/* TriggerManagementAPI  */
type TriggerManagementAPI interface {
	/* ExecSample Sample task trigger */
	ExecSample(ctx context.Context, params trigger_management.ExecSampleParams) middleware.Responder
}

// Config is configuration for Handler
type Config struct {
	CustomerManagementAPI
	ProductManagementAPI
	ResellerManagementAPI
	StatusManagementAPI
	TriggerManagementAPI
	Logger func(string, ...interface{})
	// InnerMiddleware is for the handler executors. These do not apply to the swagger.json document.
	// The middleware executes after routing but before authentication, binding and validation
	InnerMiddleware func(http.Handler) http.Handler

	// Authorizer is used to authorize a request after the Auth function was called using the "Auth*" functions
	// and the principal was stored in the context in the "AuthKey" context value.
	Authorizer func(*http.Request) error

	// AuthAPIKeyHeader Applies when the "X-API-KEY" header is set
	AuthAPIKeyHeader func(token string) (interface{}, error)

	// AuthAPIKeyParam Applies when the "api_key" query is set
	AuthAPIKeyParam func(token string) (interface{}, error)

	// AuthKeycloak For OAuth2 authentication
	AuthKeycloak func(token string, scopes []string) (interface{}, error)
}

// Handler returns an http.Handler given the handler configuration
// It mounts all the business logic implementers in the right routing.
func Handler(c Config) (http.Handler, error) {
	h, _, err := HandlerAPI(c)
	return h, err
}

// HandlerAPI returns an http.Handler given the handler configuration
// and the corresponding *CustomerDatabaseManagement instance.
// It mounts all the business logic implementers in the right routing.
func HandlerAPI(c Config) (http.Handler, *operations.CustomerDatabaseManagementAPI, error) {
	spec, err := loads.Analyzed(swaggerCopy(SwaggerJSON), "")
	if err != nil {
		return nil, nil, fmt.Errorf("analyze swagger: %v", err)
	}
	api := operations.NewCustomerDatabaseManagementAPI(spec)
	api.ServeError = errors.ServeError
	api.Logger = c.Logger

	api.JSONConsumer = runtime.JSONConsumer()
	api.JSONProducer = runtime.JSONProducer()
	api.APIKeyHeaderAuth = func(token string) (interface{}, error) {
		if c.AuthAPIKeyHeader == nil {
			return token, nil
		}
		return c.AuthAPIKeyHeader(token)
	}

	api.APIKeyParamAuth = func(token string) (interface{}, error) {
		if c.AuthAPIKeyParam == nil {
			return token, nil
		}
		return c.AuthAPIKeyParam(token)
	}

	api.KeycloakAuth = func(token string, scopes []string) (interface{}, error) {
		if c.AuthKeycloak == nil {
			return token, nil
		}
		return c.AuthKeycloak(token, scopes)
	}
	api.APIAuthorizer = authorizer(c.Authorizer)
	api.CustomerManagementAddCustomerHandler = customer_management.AddCustomerHandlerFunc(func(params customer_management.AddCustomerParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.CustomerManagementAPI.AddCustomer(ctx, params)
	})
	api.ProductManagementAddProductHandler = product_management.AddProductHandlerFunc(func(params product_management.AddProductParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.ProductManagementAPI.AddProduct(ctx, params)
	})
	api.ResellerManagementAddResellerHandler = reseller_management.AddResellerHandlerFunc(func(params reseller_management.AddResellerParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.ResellerManagementAPI.AddReseller(ctx, params)
	})
	api.TriggerManagementExecSampleHandler = trigger_management.ExecSampleHandlerFunc(func(params trigger_management.ExecSampleParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.TriggerManagementAPI.ExecSample(ctx, params)
	})
	api.CustomerManagementGetCustomerHandler = customer_management.GetCustomerHandlerFunc(func(params customer_management.GetCustomerParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.CustomerManagementAPI.GetCustomer(ctx, params)
	})
	api.ProductManagementGetProductHandler = product_management.GetProductHandlerFunc(func(params product_management.GetProductParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.ProductManagementAPI.GetProduct(ctx, params)
	})
	api.ResellerManagementGetResellerHandler = reseller_management.GetResellerHandlerFunc(func(params reseller_management.GetResellerParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.ResellerManagementAPI.GetReseller(ctx, params)
	})
	api.StatusManagementGetStatusHandler = status_management.GetStatusHandlerFunc(func(params status_management.GetStatusParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.StatusManagementAPI.GetStatus(ctx, params)
	})
	api.CustomerManagementListCustomersHandler = customer_management.ListCustomersHandlerFunc(func(params customer_management.ListCustomersParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.CustomerManagementAPI.ListCustomers(ctx, params)
	})
	api.ProductManagementListProductsHandler = product_management.ListProductsHandlerFunc(func(params product_management.ListProductsParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.ProductManagementAPI.ListProducts(ctx, params)
	})
	api.ResellerManagementListResellersHandler = reseller_management.ListResellersHandlerFunc(func(params reseller_management.ListResellersParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.ResellerManagementAPI.ListResellers(ctx, params)
	})
	api.StatusManagementShowStatusHandler = status_management.ShowStatusHandlerFunc(func(params status_management.ShowStatusParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.StatusManagementAPI.ShowStatus(ctx, params)
	})
	api.CustomerManagementUpdateCustomerHandler = customer_management.UpdateCustomerHandlerFunc(func(params customer_management.UpdateCustomerParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.CustomerManagementAPI.UpdateCustomer(ctx, params)
	})
	api.ProductManagementUpdateProductHandler = product_management.UpdateProductHandlerFunc(func(params product_management.UpdateProductParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.ProductManagementAPI.UpdateProduct(ctx, params)
	})
	api.ResellerManagementUpdateResellerHandler = reseller_management.UpdateResellerHandlerFunc(func(params reseller_management.UpdateResellerParams, principal interface{}) middleware.Responder {
		ctx := params.HTTPRequest.Context()
		ctx = storeAuth(ctx, principal)
		return c.ResellerManagementAPI.UpdateReseller(ctx, params)
	})
	api.ServerShutdown = func() {}
	return api.Serve(c.InnerMiddleware), api, nil
}

// swaggerCopy copies the swagger json to prevent data races in runtime
func swaggerCopy(orig json.RawMessage) json.RawMessage {
	c := make(json.RawMessage, len(orig))
	copy(c, orig)
	return c
}

// authorizer is a helper function to implement the runtime.Authorizer interface.
type authorizer func(*http.Request) error

func (a authorizer) Authorize(req *http.Request, principal interface{}) error {
	if a == nil {
		return nil
	}
	ctx := storeAuth(req.Context(), principal)
	return a(req.WithContext(ctx))
}

func storeAuth(ctx context.Context, principal interface{}) context.Context {
	return context.WithValue(ctx, AuthKey, principal)
}
