package customizations

import (
	
	

	
	v4 
	
	
)

type signerVersionKey struct{}

// GetSignerVersion retrieves the signer version to use for signing
//
// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues
// to clear all stack values.
func ( context.Context) ( string) {
	, _ = middleware.GetStackValue(, signerVersionKey{}).(string)
	return 
}

// SetSignerVersion sets the signer version to be used for signing the request
//
// Scoped to stack values. Use github.com/aws/smithy-go/middleware#ClearStackValues
// to clear all stack values.
func ( context.Context,  string) context.Context {
	return middleware.WithStackValue(, signerVersionKey{}, )
}

// SignHTTPRequestMiddlewareOptions is the configuration options for the SignHTTPRequestMiddleware middleware.
type SignHTTPRequestMiddlewareOptions struct {

	// credential provider
	CredentialsProvider aws.CredentialsProvider

	// log signing
	LogSigning bool

	// v4 signer
	V4Signer v4.HTTPSigner

	//v4a signer
	V4aSigner v4a.HTTPSigner
}

// NewSignHTTPRequestMiddleware constructs a SignHTTPRequestMiddleware using the given Signer for signing requests
func ( SignHTTPRequestMiddlewareOptions) *SignHTTPRequestMiddleware {
	return &SignHTTPRequestMiddleware{
		credentialsProvider: .CredentialsProvider,
		v4Signer:            .V4Signer,
		v4aSigner:           .V4aSigner,
		logSigning:          .LogSigning,
	}
}

// SignHTTPRequestMiddleware is a `FinalizeMiddleware` implementation to select HTTP Signing method
type SignHTTPRequestMiddleware struct {

	// credential provider
	credentialsProvider aws.CredentialsProvider

	// log signing
	logSigning bool

	// v4 signer
	v4Signer v4.HTTPSigner

	//v4a signer
	v4aSigner v4a.HTTPSigner
}

// ID is the SignHTTPRequestMiddleware identifier
func ( *SignHTTPRequestMiddleware) () string {
	return "Signing"
}

// HandleFinalize will take the provided input and sign the request using the SigV4 authentication scheme
func ( *SignHTTPRequestMiddleware) ( context.Context,  middleware.FinalizeInput,  middleware.FinalizeHandler) (
	 middleware.FinalizeOutput,  middleware.Metadata,  error,
) {
	// fetch signer type from context
	 := GetSignerVersion()

	switch  {
	case v4a.Version:
		,  := .credentialsProvider.(v4a.CredentialsProvider)
		if ! {
			return , , fmt.Errorf("invalid credential-provider provided for sigV4a Signer")
		}

		 := v4a.NewSignHTTPRequestMiddleware(v4a.SignHTTPRequestMiddlewareOptions{
			Credentials: ,
			Signer:      .v4aSigner,
			LogSigning:  .logSigning,
		})
		return .HandleFinalize(, , )

	default:
		 := v4.NewSignHTTPRequestMiddleware(v4.SignHTTPRequestMiddlewareOptions{
			CredentialsProvider: .credentialsProvider,
			Signer:              .v4Signer,
			LogSigning:          .logSigning,
		})
		return .HandleFinalize(, , )
	}
}

// RegisterSigningMiddleware registers the wrapper signing middleware to the stack. If a signing middleware is already
// present, this provided middleware will be swapped. Otherwise the middleware will be added at the tail of the
// finalize step.
func ( *middleware.Stack,  *SignHTTPRequestMiddleware) ( error) {
	const  = "Signing"
	,  := .Finalize.Get()
	if  {
		_,  = .Finalize.Swap(, )
	} else {
		 = .Finalize.Add(, middleware.After)
	}
	return 
}

// PresignHTTPRequestMiddlewareOptions is the options for the PresignHTTPRequestMiddleware middleware.
type PresignHTTPRequestMiddlewareOptions struct {
	CredentialsProvider aws.CredentialsProvider
	V4Presigner         v4.HTTPPresigner
	V4aPresigner        v4a.HTTPPresigner
	LogSigning          bool
}

// PresignHTTPRequestMiddleware provides the Finalize middleware for creating a
// presigned URL for an HTTP request.
//
// Will short circuit the middleware stack and not forward onto the next
// Finalize handler.
type PresignHTTPRequestMiddleware struct {

	// cred provider and signer for sigv4
	credentialsProvider aws.CredentialsProvider

	// sigV4 signer
	v4Signer v4.HTTPPresigner

	// sigV4a signer
	v4aSigner v4a.HTTPPresigner

	// log signing
	logSigning bool
}

// NewPresignHTTPRequestMiddleware constructs a PresignHTTPRequestMiddleware using the given Signer for signing requests
func ( PresignHTTPRequestMiddlewareOptions) *PresignHTTPRequestMiddleware {
	return &PresignHTTPRequestMiddleware{
		credentialsProvider: .CredentialsProvider,
		v4Signer:            .V4Presigner,
		v4aSigner:           .V4aPresigner,
		logSigning:          .LogSigning,
	}
}

// ID provides the middleware ID.
func (*PresignHTTPRequestMiddleware) () string { return "PresignHTTPRequest" }

// HandleFinalize will take the provided input and create a presigned url for
// the http request using the SigV4 or SigV4a presign authentication scheme.
//
// Since the signed request is not a valid HTTP request
func ( *PresignHTTPRequestMiddleware) (
	 context.Context,  middleware.FinalizeInput,  middleware.FinalizeHandler,
) (
	 middleware.FinalizeOutput,  middleware.Metadata,  error,
) {
	// fetch signer type from context
	 := GetSignerVersion()

	switch  {
	case v4a.Version:
		,  := .credentialsProvider.(v4a.CredentialsProvider)
		if ! {
			return , , fmt.Errorf("invalid credential-provider provided for sigV4a Signer")
		}

		 := v4a.NewPresignHTTPRequestMiddleware(v4a.PresignHTTPRequestMiddlewareOptions{
			CredentialsProvider: ,
			Presigner:           .v4aSigner,
			LogSigning:          .logSigning,
		})
		return .HandleFinalize(, , )

	default:
		 := v4.NewPresignHTTPRequestMiddleware(v4.PresignHTTPRequestMiddlewareOptions{
			CredentialsProvider: .credentialsProvider,
			Presigner:           .v4Signer,
			LogSigning:          .logSigning,
		})
		return .HandleFinalize(, , )
	}
}

// RegisterPreSigningMiddleware registers the wrapper pre-signing middleware to the stack. If a pre-signing middleware is already
// present, this provided middleware will be swapped. Otherwise the middleware will be added at the tail of the
// finalize step.
func ( *middleware.Stack,  *PresignHTTPRequestMiddleware) ( error) {
	const  = "PresignHTTPRequest"
	,  := .Finalize.Get()
	if  {
		_,  = .Finalize.Swap(, )
	} else {
		 = .Finalize.Add(, middleware.After)
	}
	return 
}