// Code generated by smithy-go-codegen DO NOT EDIT.

package s3

import (
	
	
	
	
	awsmiddleware 
	
	
	awshttp 
	internalConfig 
	
	acceptencodingcust 
	internalChecksum 
	presignedurlcust 
	
	s3sharedconfig 
	s3cust 
	smithy 
	smithydocument 
	
	
	smithyhttp 
	
	
	
)

const ServiceID = "S3"
const ServiceAPIVersion = "2006-03-01"

// Client provides the API client to make operations call for Amazon Simple Storage
// Service.
type Client struct {
	options Options
}

// New returns an initialized Client based on the functional options. Provide
// additional functional options to further configure the behavior of the client,
// such as changing the client's endpoint or adding custom middleware behavior.
func ( Options,  ...func(*Options)) *Client {
	 = .Copy()

	resolveDefaultLogger(&)

	setResolvedDefaultsMode(&)

	resolveRetryer(&)

	resolveHTTPClient(&)

	resolveHTTPSignerV4(&)

	resolveDefaultEndpointConfiguration(&)

	resolveHTTPSignerV4a(&)

	for ,  := range  {
		(&)
	}

	resolveCredentialProvider(&)

	 := &Client{
		options: ,
	}

	return 
}

type Options struct {
	// Set of options to modify how an operation is invoked. These apply to all
	// operations invoked for this client. Use functional options on operation call to
	// modify this list for per operation behavior.
	APIOptions []func(*middleware.Stack) error

	// Configures the events that will be sent to the configured logger.
	ClientLogMode aws.ClientLogMode

	// The credentials object to use when signing requests.
	Credentials aws.CredentialsProvider

	// The configuration DefaultsMode that the SDK should use when constructing the
	// clients initial default settings.
	DefaultsMode aws.DefaultsMode

	// Allows you to disable S3 Multi-Region access points feature.
	DisableMultiRegionAccessPoints bool

	// The endpoint options to be used when attempting to resolve an endpoint.
	EndpointOptions EndpointResolverOptions

	// The service endpoint resolver.
	EndpointResolver EndpointResolver

	// Signature Version 4 (SigV4) Signer
	HTTPSignerV4 HTTPSignerV4

	// The logger writer interface to write logging messages to.
	Logger logging.Logger

	// The region to send requests to. (Required)
	Region string

	// RetryMaxAttempts specifies the maximum number attempts an API client will call
	// an operation that fails with a retryable error. A value of 0 is ignored, and
	// will not be used to configure the API client created default retryer, or modify
	// per operation call's retry max attempts. When creating a new API Clients this
	// member will only be used if the Retryer Options member is nil. This value will
	// be ignored if Retryer is not nil. If specified in an operation call's functional
	// options with a value that is different than the constructed client's Options,
	// the Client's Retryer will be wrapped to use the operation's specific
	// RetryMaxAttempts value.
	RetryMaxAttempts int

	// RetryMode specifies the retry mode the API client will be created with, if
	// Retryer option is not also specified. When creating a new API Clients this
	// member will only be used if the Retryer Options member is nil. This value will
	// be ignored if Retryer is not nil. Currently does not support per operation call
	// overrides, may in the future.
	RetryMode aws.RetryMode

	// Retryer guides how HTTP requests should be retried in case of recoverable
	// failures. When nil the API client will use a default retryer. The kind of
	// default retry created by the API client can be changed with the RetryMode
	// option.
	Retryer aws.Retryer

	// The RuntimeEnvironment configuration, only populated if the DefaultsMode is set
	// to DefaultsModeAuto and is initialized using config.LoadDefaultConfig. You
	// should not populate this structure programmatically, or rely on the values here
	// within your applications.
	RuntimeEnvironment aws.RuntimeEnvironment

	// Allows you to enable arn region support for the service.
	UseARNRegion bool

	// Allows you to enable S3 Accelerate feature. All operations compatible with S3
	// Accelerate will use the accelerate endpoint for requests. Requests not
	// compatible will fall back to normal S3 requests. The bucket must be enabled for
	// accelerate to be used with S3 client with accelerate enabled. If the bucket is
	// not enabled for accelerate an error will be returned. The bucket name must be
	// DNS compatible to work with accelerate.
	UseAccelerate bool

	// Allows you to enable dual-stack endpoint support for the service.
	//
	// Deprecated: Set dual-stack by setting UseDualStackEndpoint on
	// EndpointResolverOptions. When EndpointResolverOptions' UseDualStackEndpoint
	// field is set it overrides this field value.
	UseDualstack bool

	// Allows you to enable the client to use path-style addressing, i.e.,
	// https://s3.amazonaws.com/BUCKET/KEY. By default, the S3 client will use virtual
	// hosted bucket addressing when possible(https://BUCKET.s3.amazonaws.com/KEY).
	UsePathStyle bool

	// Signature Version 4a (SigV4a) Signer
	httpSignerV4a httpSignerV4a

	// The initial DefaultsMode used when the client options were constructed. If the
	// DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved
	// value was at that point in time. Currently does not support per operation call
	// overrides, may in the future.
	resolvedDefaultsMode aws.DefaultsMode

	// The HTTP client to invoke API calls with. Defaults to client's default HTTP
	// implementation if nil.
	HTTPClient HTTPClient
}

// WithAPIOptions returns a functional option for setting the Client's APIOptions
// option.
func ( ...func(*middleware.Stack) error) func(*Options) {
	return func( *Options) {
		.APIOptions = append(.APIOptions, ...)
	}
}

// WithEndpointResolver returns a functional option for setting the Client's
// EndpointResolver option.
func ( EndpointResolver) func(*Options) {
	return func( *Options) {
		.EndpointResolver = 
	}
}

type HTTPClient interface {
	Do(*http.Request) (*http.Response, error)
}

// Copy creates a clone where the APIOptions list is deep copied.
func ( Options) () Options {
	 := 
	.APIOptions = make([]func(*middleware.Stack) error, len(.APIOptions))
	copy(.APIOptions, .APIOptions)

	return 
}
func ( *Client) ( context.Context,  string,  interface{},  []func(*Options),  ...func(*middleware.Stack, Options) error) ( interface{},  middleware.Metadata,  error) {
	 = middleware.ClearStackValues()
	 := middleware.NewStack(, smithyhttp.NewStackRequest)
	 := .options.Copy()
	for ,  := range  {
		(&)
	}

	setSafeEventStreamClientLogMode(&, )

	finalizeRetryMaxAttemptOptions(&, *)

	finalizeClientEndpointResolverOptions(&)

	resolveCredentialProvider(&)

	for ,  := range  {
		if  := (, );  != nil {
			return nil, , 
		}
	}

	for ,  := range .APIOptions {
		if  := ();  != nil {
			return nil, , 
		}
	}

	 := middleware.DecorateHandler(smithyhttp.NewClientHandler(.HTTPClient), )
	, ,  = .Handle(, )
	if  != nil {
		 = &smithy.OperationError{
			ServiceID:     ServiceID,
			OperationName: ,
			Err:           ,
		}
	}
	return , , 
}

type noSmithyDocumentSerde = smithydocument.NoSerde

func ( *Options) {
	if .Logger != nil {
		return
	}
	.Logger = logging.Nop{}
}

func ( *middleware.Stack,  Options) error {
	return middleware.AddSetLoggerMiddleware(, .Logger)
}

func ( *Options) {
	if len(.resolvedDefaultsMode) > 0 {
		return
	}

	var  aws.DefaultsMode
	.SetFromString(string(.DefaultsMode))

	if  == aws.DefaultsModeAuto {
		 = defaults.ResolveDefaultsModeAuto(.Region, .RuntimeEnvironment)
	}

	.resolvedDefaultsMode = 
}

// NewFromConfig returns a new client from the provided config.
func ( aws.Config,  ...func(*Options)) *Client {
	 := Options{
		Region:             .Region,
		DefaultsMode:       .DefaultsMode,
		RuntimeEnvironment: .RuntimeEnvironment,
		HTTPClient:         .HTTPClient,
		Credentials:        .Credentials,
		APIOptions:         .APIOptions,
		Logger:             .Logger,
		ClientLogMode:      .ClientLogMode,
	}
	resolveAWSRetryerProvider(, &)
	resolveAWSRetryMaxAttempts(, &)
	resolveAWSRetryMode(, &)
	resolveAWSEndpointResolver(, &)
	resolveUseARNRegion(, &)
	resolveUseDualStackEndpoint(, &)
	resolveUseFIPSEndpoint(, &)
	return New(, ...)
}

func ( *Options) {
	var  *awshttp.BuildableClient

	if .HTTPClient != nil {
		var  bool
		,  = .HTTPClient.(*awshttp.BuildableClient)
		if ! {
			return
		}
	} else {
		 = awshttp.NewBuildableClient()
	}

	,  := defaults.GetModeConfiguration(.resolvedDefaultsMode)
	if  == nil {
		 = .WithDialerOptions(func( *net.Dialer) {
			if ,  := .GetConnectTimeout();  {
				.Timeout = 
			}
		})

		 = .WithTransportOptions(func( *http.Transport) {
			if ,  := .GetTLSNegotiationTimeout();  {
				.TLSHandshakeTimeout = 
			}
		})
	}

	.HTTPClient = 
}

func ( *Options) {
	if .Retryer != nil {
		return
	}

	if len(.RetryMode) == 0 {
		,  := defaults.GetModeConfiguration(.resolvedDefaultsMode)
		if  == nil {
			.RetryMode = .RetryMode
		}
	}
	if len(.RetryMode) == 0 {
		.RetryMode = aws.RetryModeStandard
	}

	var  []func(*retry.StandardOptions)
	if  := .RetryMaxAttempts;  != 0 {
		 = append(, func( *retry.StandardOptions) {
			.MaxAttempts = 
		})
	}

	switch .RetryMode {
	case aws.RetryModeAdaptive:
		var  []func(*retry.AdaptiveModeOptions)
		if len() != 0 {
			 = append(, func( *retry.AdaptiveModeOptions) {
				.StandardOptions = append(.StandardOptions, ...)
			})
		}
		.Retryer = retry.NewAdaptiveMode(...)

	default:
		.Retryer = retry.NewStandard(...)
	}
}

func ( aws.Config,  *Options) {
	if .Retryer == nil {
		return
	}
	.Retryer = .Retryer()
}

func ( aws.Config,  *Options) {
	if len(.RetryMode) == 0 {
		return
	}
	.RetryMode = .RetryMode
}
func ( aws.Config,  *Options) {
	if .RetryMaxAttempts == 0 {
		return
	}
	.RetryMaxAttempts = .RetryMaxAttempts
}

func ( *Options,  Client) {
	if  := .RetryMaxAttempts;  == 0 ||  == .options.RetryMaxAttempts {
		return
	}

	.Retryer = retry.AddWithMaxAttempts(.Retryer, .RetryMaxAttempts)
}

func ( aws.Config,  *Options) {
	if .EndpointResolver == nil && .EndpointResolverWithOptions == nil {
		return
	}
	.EndpointResolver = withEndpointResolver(.EndpointResolver, .EndpointResolverWithOptions, NewDefaultEndpointResolver())
}

func ( *middleware.Stack) error {
	return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "s3", goModuleVersion)()
}

func ( *middleware.Stack,  Options) error {
	 := v4.NewSignHTTPRequestMiddleware(v4.SignHTTPRequestMiddlewareOptions{
		CredentialsProvider: .Credentials,
		Signer:              .HTTPSignerV4,
		LogSigning:          .ClientLogMode.IsSigning(),
	})
	return .Finalize.Add(, middleware.After)
}

type HTTPSignerV4 interface {
	SignHTTP(ctx context.Context, credentials aws.Credentials, r *http.Request, payloadHash string, service string, region string, signingTime time.Time, optFns ...func(*v4.SignerOptions)) error
}

func ( *Options) {
	if .HTTPSignerV4 != nil {
		return
	}
	.HTTPSignerV4 = newDefaultV4Signer(*)
}

func ( Options) *v4.Signer {
	return v4.NewSigner(func( *v4.SignerOptions) {
		.Logger = .Logger
		.LogSigning = .ClientLogMode.IsSigning()
		.DisableURIPathEscaping = true
	})
}

func ( *middleware.Stack,  Options) error {
	 := retry.AddRetryMiddlewaresOptions{
		Retryer:          .Retryer,
		LogRetryAttempts: .ClientLogMode.IsRetries(),
	}
	return retry.AddRetryMiddlewares(, )
}

// resolves UseARNRegion S3 configuration
func ( aws.Config,  *Options) error {
	if len(.ConfigSources) == 0 {
		return nil
	}
	, ,  := s3sharedconfig.ResolveUseARNRegion(context.Background(), .ConfigSources)
	if  != nil {
		return 
	}
	if  {
		.UseARNRegion = 
	}
	return nil
}

// resolves dual-stack endpoint configuration
func ( aws.Config,  *Options) error {
	if len(.ConfigSources) == 0 {
		return nil
	}
	, ,  := internalConfig.ResolveUseDualStackEndpoint(context.Background(), .ConfigSources)
	if  != nil {
		return 
	}
	if  {
		.EndpointOptions.UseDualStackEndpoint = 
	}
	return nil
}

// resolves FIPS endpoint configuration
func ( aws.Config,  *Options) error {
	if len(.ConfigSources) == 0 {
		return nil
	}
	, ,  := internalConfig.ResolveUseFIPSEndpoint(context.Background(), .ConfigSources)
	if  != nil {
		return 
	}
	if  {
		.EndpointOptions.UseFIPSEndpoint = 
	}
	return nil
}

func ( *Options) {
	if .Credentials == nil {
		return
	}

	if ,  := .Credentials.(v4a.CredentialsProvider);  {
		return
	}

	if aws.IsCredentialsProvider(.Credentials, (*aws.AnonymousCredentials)(nil)) {
		return
	}

	.Credentials = &v4a.SymmetricCredentialAdaptor{SymmetricProvider: .Credentials}
}

func ( *middleware.Stack,  Options) error {
	 := s3cust.NewSignHTTPRequestMiddleware(s3cust.SignHTTPRequestMiddlewareOptions{
		CredentialsProvider: .Credentials,
		V4Signer:            .HTTPSignerV4,
		V4aSigner:           .httpSignerV4a,
		LogSigning:          .ClientLogMode.IsSigning(),
	})

	return s3cust.RegisterSigningMiddleware(, )
}

type httpSignerV4a interface {
	SignHTTP(ctx context.Context, credentials v4a.Credentials, r *http.Request, payloadHash,
		service string, regionSet []string, signingTime time.Time,
		optFns ...func(*v4a.SignerOptions)) error
}

func ( *Options) {
	if .httpSignerV4a != nil {
		return
	}
	.httpSignerV4a = newDefaultV4aSigner(*)
}

func ( Options) *v4a.Signer {
	return v4a.NewSigner(func( *v4a.SignerOptions) {
		.Logger = .Logger
		.LogSigning = .ClientLogMode.IsSigning()
		.DisableURIPathEscaping = true
	})
}

func ( *middleware.Stack) error {
	return s3shared.AddMetadataRetrieverMiddleware()
}

// ComputedInputChecksumsMetadata provides information about the algorithms used to
// compute the checksum(s) of the input payload.
type ComputedInputChecksumsMetadata struct {
	// ComputedChecksums is a map of algorithm name to checksum value of the computed
	// input payload's checksums.
	ComputedChecksums map[string]string
}

// GetComputedInputChecksumsMetadata retrieves from the result metadata the map of
// algorithms and input payload checksums values.
func ( middleware.Metadata) (ComputedInputChecksumsMetadata, bool) {
	,  := internalChecksum.GetComputedInputChecksums()
	if ! {
		return ComputedInputChecksumsMetadata{}, false
	}
	return ComputedInputChecksumsMetadata{
		ComputedChecksums: ,
	}, true

}

// ChecksumValidationMetadata contains metadata such as the checksum algorithm used
// for data integrity validation.
type ChecksumValidationMetadata struct {
	// AlgorithmsUsed is the set of the checksum algorithms used to validate the
	// response payload. The response payload must be completely read in order for the
	// checksum validation to be performed. An error is returned by the operation
	// output's response io.ReadCloser if the computed checksums are invalid.
	AlgorithmsUsed []string
}

// GetChecksumValidationMetadata returns the set of algorithms that will be used to
// validate the response payload with. The response payload must be completely read
// in order for the checksum validation to be performed. An error is returned by
// the operation output's response io.ReadCloser if the computed checksums are
// invalid. Returns false if no checksum algorithm used metadata was found.
func ( middleware.Metadata) (ChecksumValidationMetadata, bool) {
	,  := internalChecksum.GetOutputValidationAlgorithmsUsed()
	if ! {
		return ChecksumValidationMetadata{}, false
	}
	return ChecksumValidationMetadata{
		AlgorithmsUsed: append(make([]string, 0, len()), ...),
	}, true

}

// nopGetBucketAccessor is no-op accessor for operation that don't support bucket
// member as input
func ( interface{}) (*string, bool) {
	return nil, false
}

func ( *middleware.Stack) error {
	return s3shared.AddResponseErrorMiddleware()
}

func ( *middleware.Stack) error {
	return acceptencodingcust.AddAcceptEncodingGzip(, acceptencodingcust.AddAcceptEncodingGzipOptions{})
}

// ResponseError provides the HTTP centric error type wrapping the underlying error
// with the HTTP response value and the deserialized RequestID.
type ResponseError interface {
	error

	ServiceHostID() string
	ServiceRequestID() string
}

var _ ResponseError = (*s3shared.ResponseError)(nil)

// GetHostIDMetadata retrieves the host id from middleware metadata returns host id
// as string along with a boolean indicating presence of hostId on middleware
// metadata.
func ( middleware.Metadata) (string, bool) {
	return s3shared.GetHostIDMetadata()
}

// HTTPPresignerV4 represents presigner interface used by presign url client
type HTTPPresignerV4 interface {
	PresignHTTP(
		ctx context.Context, credentials aws.Credentials, r *http.Request,
		payloadHash string, service string, region string, signingTime time.Time,
		optFns ...func(*v4.SignerOptions),
	) (url string, signedHeader http.Header, err error)
}

// httpPresignerV4a represents sigv4a presigner interface used by presign url
// client
type httpPresignerV4a interface {
	PresignHTTP(
		ctx context.Context, credentials v4a.Credentials, r *http.Request,
		payloadHash string, service string, regionSet []string, signingTime time.Time,
		optFns ...func(*v4a.SignerOptions),
	) (url string, signedHeader http.Header, err error)
}

// PresignOptions represents the presign client options
type PresignOptions struct {

	// ClientOptions are list of functional options to mutate client options used by
	// the presign client.
	ClientOptions []func(*Options)

	// Presigner is the presigner used by the presign url client
	Presigner HTTPPresignerV4

	// Expires sets the expiration duration for the generated presign url. This should
	// be the duration in seconds the presigned URL should be considered valid for. If
	// not set or set to zero, presign url would default to expire after 900 seconds.
	Expires time.Duration

	// presignerV4a is the presigner used by the presign url client
	presignerV4a httpPresignerV4a
}

func ( PresignOptions) () PresignOptions {
	 := make([]func(*Options), len(.ClientOptions))
	copy(, .ClientOptions)
	.ClientOptions = 
	return 
}

// WithPresignClientFromClientOptions is a helper utility to retrieve a function
// that takes PresignOption as input
func ( ...func(*Options)) func(*PresignOptions) {
	return withPresignClientFromClientOptions().options
}

type withPresignClientFromClientOptions []func(*Options)

func ( withPresignClientFromClientOptions) ( *PresignOptions) {
	.ClientOptions = append(.ClientOptions, ...)
}

// WithPresignExpires is a helper utility to append Expires value on presign
// options optional function
func ( time.Duration) func(*PresignOptions) {
	return withPresignExpires().options
}

type withPresignExpires time.Duration

func ( withPresignExpires) ( *PresignOptions) {
	.Expires = time.Duration()
}

// PresignClient represents the presign url client
type PresignClient struct {
	client  *Client
	options PresignOptions
}

// NewPresignClient generates a presign client using provided API Client and
// presign options
func ( *Client,  ...func(*PresignOptions)) *PresignClient {
	var  PresignOptions
	for ,  := range  {
		(&)
	}
	if len(.ClientOptions) != 0 {
		 = New(.options, .ClientOptions...)
	}

	if .Presigner == nil {
		.Presigner = newDefaultV4Signer(.options)
	}

	if .presignerV4a == nil {
		.presignerV4a = newDefaultV4aSigner(.options)
	}

	return &PresignClient{
		client:  ,
		options: ,
	}
}

func ( *Options) {
	.HTTPClient = smithyhttp.NopClient{}
}

type presignConverter PresignOptions

func ( presignConverter) ( *middleware.Stack,  Options) ( error) {
	.Finalize.Clear()
	.Deserialize.Clear()
	.Build.Remove((*awsmiddleware.ClientRequestID)(nil).ID())
	.Build.Remove("UserAgent")
	 := v4.NewPresignHTTPRequestMiddleware(v4.PresignHTTPRequestMiddlewareOptions{
		CredentialsProvider: .Credentials,
		Presigner:           .Presigner,
		LogSigning:          .ClientLogMode.IsSigning(),
	})
	 = .Finalize.Add(, middleware.After)
	if  != nil {
		return 
	}
	if  = smithyhttp.AddNoPayloadDefaultContentTypeRemover();  != nil {
		return 
	}

	// add multi-region access point presigner
	 := s3cust.NewPresignHTTPRequestMiddleware(s3cust.PresignHTTPRequestMiddlewareOptions{
		CredentialsProvider: .Credentials,
		V4Presigner:         .Presigner,
		V4aPresigner:        .presignerV4a,
		LogSigning:          .ClientLogMode.IsSigning(),
	})
	 = s3cust.RegisterPreSigningMiddleware(, )
	if  != nil {
		return 
	}

	if .Expires < 0 {
		return fmt.Errorf("presign URL duration must be 0 or greater, %v", .Expires)
	}
	// add middleware to set expiration for s3 presigned url, if expiration is set to
	// 0, this middleware sets a default expiration of 900 seconds
	 = .Build.Add(&s3cust.AddExpiresOnPresignedURL{Expires: .Expires}, middleware.After)
	if  != nil {
		return 
	}
	 = presignedurlcust.AddAsIsPresigingMiddleware()
	if  != nil {
		return 
	}
	return nil
}

func ( *middleware.Stack,  Options) error {
	return .Deserialize.Add(&smithyhttp.RequestResponseLogger{
		LogRequest:          .ClientLogMode.IsRequest(),
		LogRequestWithBody:  .ClientLogMode.IsRequestWithBody(),
		LogResponse:         .ClientLogMode.IsResponse(),
		LogResponseWithBody: .ClientLogMode.IsResponseWithBody(),
	}, middleware.After)
}