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

package s3

import (
	
	
	
	
	awsmiddleware 
	internalendpoints 
	
	smithyhttp 
	
	
)

// EndpointResolverOptions is the service endpoint resolver options
type EndpointResolverOptions = internalendpoints.Options

// EndpointResolver interface for resolving service endpoints.
type EndpointResolver interface {
	ResolveEndpoint(region string, options EndpointResolverOptions) (aws.Endpoint, error)
}

var _ EndpointResolver = &internalendpoints.Resolver{}

// NewDefaultEndpointResolver constructs a new service endpoint resolver
func () *internalendpoints.Resolver {
	return internalendpoints.New()
}

// EndpointResolverFunc is a helper utility that wraps a function so it satisfies
// the EndpointResolver interface. This is useful when you want to add additional
// endpoint resolving logic, or stub out specific endpoints with custom values.
type EndpointResolverFunc func(region string, options EndpointResolverOptions) (aws.Endpoint, error)

func ( EndpointResolverFunc) ( string,  EndpointResolverOptions) ( aws.Endpoint,  error) {
	return (, )
}

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

// EndpointResolverFromURL returns an EndpointResolver configured using the
// provided endpoint url. By default, the resolved endpoint resolver uses the
// client region as signing region, and the endpoint source is set to
// EndpointSourceCustom.You can provide functional options to configure endpoint
// values for the resolved endpoint.
func ( string,  ...func(*aws.Endpoint)) EndpointResolver {
	 := aws.Endpoint{URL: , Source: aws.EndpointSourceCustom}
	for ,  := range  {
		(&)
	}

	return EndpointResolverFunc(
		func( string,  EndpointResolverOptions) (aws.Endpoint, error) {
			if len(.SigningRegion) == 0 {
				.SigningRegion = 
			}
			return , nil
		},
	)
}

type ResolveEndpoint struct {
	Resolver EndpointResolver
	Options  EndpointResolverOptions
}

func (*ResolveEndpoint) () string {
	return "ResolveEndpoint"
}

func ( *ResolveEndpoint) ( context.Context,  middleware.SerializeInput,  middleware.SerializeHandler) (
	 middleware.SerializeOutput,  middleware.Metadata,  error,
) {
	,  := .Request.(*smithyhttp.Request)
	if ! {
		return , , fmt.Errorf("unknown transport type %T", .Request)
	}

	if .Resolver == nil {
		return , , fmt.Errorf("expected endpoint resolver to not be nil")
	}

	 := .Options
	.Logger = middleware.GetLogger()

	var  aws.Endpoint
	,  = .Resolver.ResolveEndpoint(awsmiddleware.GetRegion(), )
	if  != nil {
		return , , fmt.Errorf("failed to resolve service endpoint, %w", )
	}

	.URL,  = url.Parse(.URL)
	if  != nil {
		return , , fmt.Errorf("failed to parse endpoint URL: %w", )
	}

	if len(awsmiddleware.GetSigningName()) == 0 {
		 := .SigningName
		if len() == 0 {
			 = "s3"
		}
		 = awsmiddleware.SetSigningName(, )
	}
	 = awsmiddleware.SetEndpointSource(, .Source)
	 = smithyhttp.SetHostnameImmutable(, .HostnameImmutable)
	 = awsmiddleware.SetSigningRegion(, .SigningRegion)
	 = awsmiddleware.SetPartitionID(, .PartitionID)
	return .HandleSerialize(, )
}
func ( *middleware.Stack,  Options) error {
	return .Serialize.Insert(&ResolveEndpoint{
		Resolver: .EndpointResolver,
		Options:  .EndpointOptions,
	}, "OperationSerializer", middleware.Before)
}

func ( *middleware.Stack) error {
	,  := .Serialize.Remove((&ResolveEndpoint{}).ID())
	return 
}

type wrappedEndpointResolver struct {
	awsResolver aws.EndpointResolverWithOptions
	resolver    EndpointResolver
}

func ( *wrappedEndpointResolver) ( string,  EndpointResolverOptions) ( aws.Endpoint,  error) {
	if .awsResolver == nil {
		goto 
	}
	,  = .awsResolver.ResolveEndpoint(ServiceID, , )
	if  == nil {
		return , nil
	}

	if  := (&aws.EndpointNotFoundError{}); !errors.As(, &) {
		return , 
	}

:
	if .resolver == nil {
		return , fmt.Errorf("default endpoint resolver provided was nil")
	}
	return .resolver.ResolveEndpoint(, )
}

type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error)

func ( awsEndpointResolverAdaptor) (,  string,  ...interface{}) (aws.Endpoint, error) {
	return (, )
}

var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil)

// withEndpointResolver returns an EndpointResolver that first delegates endpoint resolution to the awsResolver.
// If awsResolver returns aws.EndpointNotFoundError error, the resolver will use the the provided
// fallbackResolver for resolution.
//
// fallbackResolver must not be nil
func ( aws.EndpointResolver,  aws.EndpointResolverWithOptions,  EndpointResolver) EndpointResolver {
	var  aws.EndpointResolverWithOptions

	if  != nil {
		 = 
	} else if  != nil {
		 = awsEndpointResolverAdaptor(.ResolveEndpoint)
	}

	return &wrappedEndpointResolver{
		awsResolver: ,
		resolver:    ,
	}
}

func ( *Options) {
	.EndpointOptions.LogDeprecated = .ClientLogMode.IsDeprecatedUsage()

	if len(.EndpointOptions.ResolvedRegion) == 0 {
		const  = "-fips-"
		const  = "fips-"
		const  = "-fips"

		if strings.Contains(.Region, ) ||
			strings.Contains(.Region, ) ||
			strings.Contains(.Region, ) {
			.EndpointOptions.ResolvedRegion = strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(
				.Region, , "-"), , ""), , "")
			.EndpointOptions.UseFIPSEndpoint = aws.FIPSEndpointStateEnabled
		}
	}

	if .EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateUnset {
		if .UseDualstack {
			.EndpointOptions.UseDualStackEndpoint = aws.DualStackEndpointStateEnabled
		} else {
			.EndpointOptions.UseDualStackEndpoint = aws.DualStackEndpointStateDisabled
		}
	}

}