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

package dynamodb

import (
	"context"
	"errors"
	"fmt"
	"github.com/aws/aws-sdk-go-v2/aws"
	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
	internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources"
	"github.com/aws/aws-sdk-go-v2/internal/endpoints"
	"github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn"
	internalendpoints "github.com/aws/aws-sdk-go-v2/service/dynamodb/internal/endpoints"
	smithy "github.com/aws/smithy-go"
	smithyauth "github.com/aws/smithy-go/auth"
	smithyendpoints "github.com/aws/smithy-go/endpoints"
	"github.com/aws/smithy-go/endpoints/private/rulesfn"
	"github.com/aws/smithy-go/middleware"
	"github.com/aws/smithy-go/ptr"
	"github.com/aws/smithy-go/tracing"
	smithyhttp "github.com/aws/smithy-go/transport/http"
	"net/http"
	"net/url"
	"os"
	"strings"
)

// 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 NewDefaultEndpointResolver() *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 (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) {
	return fn(region, options)
}

// 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 EndpointResolverFromURL(url string, optFns ...func(*aws.Endpoint)) EndpointResolver {
	e := aws.Endpoint{URL: url, Source: aws.EndpointSourceCustom}
	for _, fn := range optFns {
		fn(&e)
	}

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

type ResolveEndpoint struct {
	Resolver EndpointResolver
	Options  EndpointResolverOptions
}

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

func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) (
	out middleware.SerializeOutput, metadata middleware.Metadata, err error,
) {
	if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
		return next.HandleSerialize(ctx, in)
	}

	req, ok := in.Request.(*smithyhttp.Request)
	if !ok {
		return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
	}

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

	eo := m.Options
	eo.Logger = middleware.GetLogger(ctx)

	var endpoint aws.Endpoint
	endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo)
	if err != nil {
		nf := (&aws.EndpointNotFoundError{})
		if errors.As(err, &nf) {
			ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, false)
			return next.HandleSerialize(ctx, in)
		}
		return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
	}

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

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

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

type wrappedEndpointResolver struct {
	awsResolver aws.EndpointResolverWithOptions
}

func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) {
	return w.awsResolver.ResolveEndpoint(ServiceID, region, options)
}

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

func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, options ...interface{}) (aws.Endpoint, error) {
	return a(service, region)
}

var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil)

// withEndpointResolver returns an aws.EndpointResolverWithOptions that first delegates endpoint resolution to the awsResolver.
// If awsResolver returns aws.EndpointNotFoundError error, the v1 resolver middleware will swallow the error,
// and set an appropriate context flag such that fallback will occur when EndpointResolverV2 is invoked
// via its middleware.
//
// If another error (besides aws.EndpointNotFoundError) is returned, then that error will be propagated.
func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions) EndpointResolver {
	var resolver aws.EndpointResolverWithOptions

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

	return &wrappedEndpointResolver{
		awsResolver: resolver,
	}
}

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

	if len(options.EndpointOptions.ResolvedRegion) == 0 {
		const fipsInfix = "-fips-"
		const fipsPrefix = "fips-"
		const fipsSuffix = "-fips"

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

}

func resolveEndpointResolverV2(options *Options) {
	if options.EndpointResolverV2 == nil {
		options.EndpointResolverV2 = NewDefaultEndpointResolverV2()
	}
}

func resolveBaseEndpoint(cfg aws.Config, o *Options) {
	if cfg.BaseEndpoint != nil {
		o.BaseEndpoint = cfg.BaseEndpoint
	}

	_, g := os.LookupEnv("AWS_ENDPOINT_URL")
	_, s := os.LookupEnv("AWS_ENDPOINT_URL_DYNAMODB")

	if g && !s {
		return
	}

	value, found, err := internalConfig.ResolveServiceBaseEndpoint(context.Background(), "DynamoDB", cfg.ConfigSources)
	if found && err == nil {
		o.BaseEndpoint = &value
	}
}

func bindRegion(region string) (*string, error) {
	if region == "" {
		return nil, nil
	}
	if !rulesfn.IsValidHostLabel(region, true) {
		return nil, fmt.Errorf("invalid input region %s", region)
	}

	return aws.String(endpoints.MapFIPSRegion(region)), nil
}

// EndpointParameters provides the parameters that influence how endpoints are
// resolved.
type EndpointParameters struct {
	// The AWS region used to dispatch the request.
	//
	// Parameter is
	// required.
	//
	// AWS::Region
	Region *string

	// When true, use the dual-stack endpoint. If the configured endpoint does not
	// support dual-stack, dispatching the request MAY return an error.
	//
	// Defaults to
	// false if no value is provided.
	//
	// AWS::UseDualStack
	UseDualStack *bool

	// When true, send this request to the FIPS-compliant regional endpoint. If the
	// configured endpoint does not have a FIPS compliant endpoint, dispatching the
	// request will return an error.
	//
	// Defaults to false if no value is
	// provided.
	//
	// AWS::UseFIPS
	UseFIPS *bool

	// Override the endpoint used to send this request
	//
	// Parameter is
	// required.
	//
	// SDK::Endpoint
	Endpoint *string

	// The AWS AccountId used for the request.
	//
	// Parameter is
	// required.
	//
	// AWS::Auth::AccountId
	AccountId *string

	// The AccountId Endpoint Mode.
	//
	// Parameter is
	// required.
	//
	// AWS::Auth::AccountIdEndpointMode
	AccountIdEndpointMode *string

	// ResourceArn containing arn of resource
	//
	// Parameter is required.
	ResourceArn *string

	// ResourceArnList containing list of resource arns
	//
	// Parameter is required.
	ResourceArnList []string
}

// ValidateRequired validates required parameters are set.
func (p EndpointParameters) ValidateRequired() error {
	if p.UseDualStack == nil {
		return fmt.Errorf("parameter UseDualStack is required")
	}

	if p.UseFIPS == nil {
		return fmt.Errorf("parameter UseFIPS is required")
	}

	return nil
}

// WithDefaults returns a shallow copy of EndpointParameterswith default values
// applied to members where applicable.
func (p EndpointParameters) WithDefaults() EndpointParameters {
	if p.UseDualStack == nil {
		p.UseDualStack = ptr.Bool(false)
	}

	if p.UseFIPS == nil {
		p.UseFIPS = ptr.Bool(false)
	}
	return p
}

type stringSlice []string

func (s stringSlice) Get(i int) *string {
	if i < 0 || i >= len(s) {
		return nil
	}

	v := s[i]
	return &v
}

// EndpointResolverV2 provides the interface for resolving service endpoints.
type EndpointResolverV2 interface {
	// ResolveEndpoint attempts to resolve the endpoint with the provided options,
	// returning the endpoint if found. Otherwise an error is returned.
	ResolveEndpoint(ctx context.Context, params EndpointParameters) (
		smithyendpoints.Endpoint, error,
	)
}

// resolver provides the implementation for resolving endpoints.
type resolver struct{}

func NewDefaultEndpointResolverV2() EndpointResolverV2 {
	return &resolver{}
}

// ResolveEndpoint attempts to resolve the endpoint with the provided options,
// returning the endpoint if found. Otherwise an error is returned.
func (r *resolver) ResolveEndpoint(
	ctx context.Context, params EndpointParameters,
) (
	endpoint smithyendpoints.Endpoint, err error,
) {
	params = params.WithDefaults()
	if err = params.ValidateRequired(); err != nil {
		return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err)
	}
	_UseDualStack := *params.UseDualStack
	_ = _UseDualStack
	_UseFIPS := *params.UseFIPS
	_ = _UseFIPS

	if exprVal := params.Endpoint; exprVal != nil {
		_Endpoint := *exprVal
		_ = _Endpoint
		if exprVal := params.Region; exprVal != nil {
			_Region := *exprVal
			_ = _Region
			if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil {
				_PartitionResult := *exprVal
				_ = _PartitionResult
				if _UseFIPS == true {
					return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported")
				}
				if _UseDualStack == true {
					return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported")
				}
				if _Endpoint == func() string {
					var out strings.Builder
					out.WriteString("https://dynamodb.")
					out.WriteString(_Region)
					out.WriteString(".")
					out.WriteString(_PartitionResult.DualStackDnsSuffix)
					return out.String()
				}() {
					return endpoint, fmt.Errorf("endpoint rule error, %s", "Endpoint override is not supported for dual-stack endpoints. Please enable dual-stack functionality by enabling the configuration. For more details, see: https://docs.aws.amazon.com/sdkref/latest/guide/feature-endpoints.html")
				}
				uriString := _Endpoint

				uri, err := url.Parse(uriString)
				if err != nil {
					return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
				}

				return smithyendpoints.Endpoint{
					URI:     *uri,
					Headers: http.Header{},
				}, nil
			}
		}
	}
	if exprVal := params.Endpoint; exprVal != nil {
		_Endpoint := *exprVal
		_ = _Endpoint
		if _UseFIPS == true {
			return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported")
		}
		if _UseDualStack == true {
			return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported")
		}
		uriString := _Endpoint

		uri, err := url.Parse(uriString)
		if err != nil {
			return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
		}

		return smithyendpoints.Endpoint{
			URI:     *uri,
			Headers: http.Header{},
		}, nil
	}
	if exprVal := params.Region; exprVal != nil {
		_Region := *exprVal
		_ = _Region
		if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil {
			_PartitionResult := *exprVal
			_ = _PartitionResult
			if _Region == "local" {
				if _UseFIPS == true {
					return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and local endpoint are not supported")
				}
				if _UseDualStack == true {
					return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and local endpoint are not supported")
				}
				uriString := "http://localhost:8000"

				uri, err := url.Parse(uriString)
				if err != nil {
					return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
				}

				return smithyendpoints.Endpoint{
					URI:     *uri,
					Headers: http.Header{},
					Properties: func() smithy.Properties {
						var out smithy.Properties
						smithyauth.SetAuthOptions(&out, []*smithyauth.Option{
							{
								SchemeID: "aws.auth#sigv4",
								SignerProperties: func() smithy.Properties {
									var sp smithy.Properties
									smithyhttp.SetSigV4SigningRegion(&sp, "us-east-1")

									smithyhttp.SetSigV4SigningName(&sp, "dynamodb")
									smithyhttp.SetSigV4ASigningName(&sp, "dynamodb")
									return sp
								}(),
							},
						})
						return out
					}(),
				}, nil
			}
			if _UseFIPS == true {
				if _UseDualStack == true {
					if _PartitionResult.SupportsFIPS == true {
						if _PartitionResult.SupportsDualStack == true {
							if exprVal := params.AccountIdEndpointMode; exprVal != nil {
								_AccountIdEndpointMode := *exprVal
								_ = _AccountIdEndpointMode
								if _AccountIdEndpointMode == "required" {
									return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: AccountIdEndpointMode is required and FIPS is enabled, but FIPS account endpoints are not supported")
								}
							}
							uriString := func() string {
								var out strings.Builder
								out.WriteString("https://dynamodb-fips.")
								out.WriteString(_Region)
								out.WriteString(".")
								out.WriteString(_PartitionResult.DualStackDnsSuffix)
								return out.String()
							}()

							uri, err := url.Parse(uriString)
							if err != nil {
								return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
							}

							return smithyendpoints.Endpoint{
								URI:     *uri,
								Headers: http.Header{},
							}, nil
						}
					}
					return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both")
				}
			}
			if _UseFIPS == true {
				if _PartitionResult.SupportsFIPS == true {
					if _PartitionResult.Name == "aws-us-gov" {
						if exprVal := params.AccountIdEndpointMode; exprVal != nil {
							_AccountIdEndpointMode := *exprVal
							_ = _AccountIdEndpointMode
							if _AccountIdEndpointMode == "required" {
								return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: AccountIdEndpointMode is required and FIPS is enabled, but FIPS account endpoints are not supported")
							}
						}
						uriString := func() string {
							var out strings.Builder
							out.WriteString("https://dynamodb.")
							out.WriteString(_Region)
							out.WriteString(".")
							out.WriteString(_PartitionResult.DnsSuffix)
							return out.String()
						}()

						uri, err := url.Parse(uriString)
						if err != nil {
							return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
						}

						return smithyendpoints.Endpoint{
							URI:     *uri,
							Headers: http.Header{},
						}, nil
					}
					if exprVal := params.AccountIdEndpointMode; exprVal != nil {
						_AccountIdEndpointMode := *exprVal
						_ = _AccountIdEndpointMode
						if _AccountIdEndpointMode == "required" {
							return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: AccountIdEndpointMode is required and FIPS is enabled, but FIPS account endpoints are not supported")
						}
					}
					uriString := func() string {
						var out strings.Builder
						out.WriteString("https://dynamodb-fips.")
						out.WriteString(_Region)
						out.WriteString(".")
						out.WriteString(_PartitionResult.DnsSuffix)
						return out.String()
					}()

					uri, err := url.Parse(uriString)
					if err != nil {
						return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
					}

					return smithyendpoints.Endpoint{
						URI:     *uri,
						Headers: http.Header{},
					}, nil
				}
				return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS")
			}
			if _UseDualStack == true {
				if _PartitionResult.SupportsDualStack == true {
					if exprVal := params.AccountIdEndpointMode; exprVal != nil {
						_AccountIdEndpointMode := *exprVal
						_ = _AccountIdEndpointMode
						if !(_AccountIdEndpointMode == "disabled") {
							if _PartitionResult.Name == "aws" {
								if !(_UseFIPS == true) {
									if exprVal := params.ResourceArn; exprVal != nil {
										_ResourceArn := *exprVal
										_ = _ResourceArn
										if exprVal := awsrulesfn.ParseARN(_ResourceArn); exprVal != nil {
											_ParsedArn := *exprVal
											_ = _ParsedArn
											if _ParsedArn.Service == "dynamodb" {
												if rulesfn.IsValidHostLabel(_ParsedArn.Region, false) {
													if _ParsedArn.Region == _Region {
														if rulesfn.IsValidHostLabel(_ParsedArn.AccountId, false) {
															uriString := func() string {
																var out strings.Builder
																out.WriteString("https://")
																out.WriteString(_ParsedArn.AccountId)
																out.WriteString(".ddb.")
																out.WriteString(_Region)
																out.WriteString(".")
																out.WriteString(_PartitionResult.DualStackDnsSuffix)
																return out.String()
															}()

															uri, err := url.Parse(uriString)
															if err != nil {
																return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
															}

															return smithyendpoints.Endpoint{
																URI:     *uri,
																Headers: http.Header{},
																Properties: func() smithy.Properties {
																	var out smithy.Properties
																	out.Set("metricValues", []interface{}{
																		"O",
																	})
																	return out
																}(),
															}, nil
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
					if exprVal := params.AccountIdEndpointMode; exprVal != nil {
						_AccountIdEndpointMode := *exprVal
						_ = _AccountIdEndpointMode
						if !(_AccountIdEndpointMode == "disabled") {
							if _PartitionResult.Name == "aws" {
								if !(_UseFIPS == true) {
									if exprVal := params.ResourceArnList; exprVal != nil {
										_ResourceArnList := stringSlice(exprVal)
										_ = _ResourceArnList
										if exprVal := _ResourceArnList.Get(0); exprVal != nil {
											_FirstArn := *exprVal
											_ = _FirstArn
											if exprVal := awsrulesfn.ParseARN(_FirstArn); exprVal != nil {
												_ParsedArn := *exprVal
												_ = _ParsedArn
												if _ParsedArn.Service == "dynamodb" {
													if rulesfn.IsValidHostLabel(_ParsedArn.Region, false) {
														if _ParsedArn.Region == _Region {
															if rulesfn.IsValidHostLabel(_ParsedArn.AccountId, false) {
																uriString := func() string {
																	var out strings.Builder
																	out.WriteString("https://")
																	out.WriteString(_ParsedArn.AccountId)
																	out.WriteString(".ddb.")
																	out.WriteString(_Region)
																	out.WriteString(".")
																	out.WriteString(_PartitionResult.DualStackDnsSuffix)
																	return out.String()
																}()

																uri, err := url.Parse(uriString)
																if err != nil {
																	return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
																}

																return smithyendpoints.Endpoint{
																	URI:     *uri,
																	Headers: http.Header{},
																	Properties: func() smithy.Properties {
																		var out smithy.Properties
																		out.Set("metricValues", []interface{}{
																			"O",
																		})
																		return out
																	}(),
																}, nil
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
					if exprVal := params.AccountIdEndpointMode; exprVal != nil {
						_AccountIdEndpointMode := *exprVal
						_ = _AccountIdEndpointMode
						if !(_AccountIdEndpointMode == "disabled") {
							if _PartitionResult.Name == "aws" {
								if !(_UseFIPS == true) {
									if exprVal := params.AccountId; exprVal != nil {
										_AccountId := *exprVal
										_ = _AccountId
										if rulesfn.IsValidHostLabel(_AccountId, false) {
											uriString := func() string {
												var out strings.Builder
												out.WriteString("https://")
												out.WriteString(_AccountId)
												out.WriteString(".ddb.")
												out.WriteString(_Region)
												out.WriteString(".")
												out.WriteString(_PartitionResult.DualStackDnsSuffix)
												return out.String()
											}()

											uri, err := url.Parse(uriString)
											if err != nil {
												return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
											}

											return smithyendpoints.Endpoint{
												URI:     *uri,
												Headers: http.Header{},
												Properties: func() smithy.Properties {
													var out smithy.Properties
													out.Set("metricValues", []interface{}{
														"O",
													})
													return out
												}(),
											}, nil
										}
										return endpoint, fmt.Errorf("endpoint rule error, %s", "Credentials-sourced account ID parameter is invalid")
									}
								}
							}
						}
					}
					if exprVal := params.AccountIdEndpointMode; exprVal != nil {
						_AccountIdEndpointMode := *exprVal
						_ = _AccountIdEndpointMode
						if _AccountIdEndpointMode == "required" {
							if !(_UseFIPS == true) {
								if _PartitionResult.Name == "aws" {
									return endpoint, fmt.Errorf("endpoint rule error, %s", "AccountIdEndpointMode is required but no AccountID was provided or able to be loaded")
								}
								return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: AccountIdEndpointMode is required but account endpoints are not supported in this partition")
							}
							return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: AccountIdEndpointMode is required and FIPS is enabled, but FIPS account endpoints are not supported")
						}
					}
					uriString := func() string {
						var out strings.Builder
						out.WriteString("https://dynamodb.")
						out.WriteString(_Region)
						out.WriteString(".")
						out.WriteString(_PartitionResult.DualStackDnsSuffix)
						return out.String()
					}()

					uri, err := url.Parse(uriString)
					if err != nil {
						return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
					}

					return smithyendpoints.Endpoint{
						URI:     *uri,
						Headers: http.Header{},
					}, nil
				}
				return endpoint, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack")
			}
			if exprVal := params.AccountIdEndpointMode; exprVal != nil {
				_AccountIdEndpointMode := *exprVal
				_ = _AccountIdEndpointMode
				if !(_AccountIdEndpointMode == "disabled") {
					if _PartitionResult.Name == "aws" {
						if !(_UseFIPS == true) {
							if exprVal := params.ResourceArn; exprVal != nil {
								_ResourceArn := *exprVal
								_ = _ResourceArn
								if exprVal := awsrulesfn.ParseARN(_ResourceArn); exprVal != nil {
									_ParsedArn := *exprVal
									_ = _ParsedArn
									if _ParsedArn.Service == "dynamodb" {
										if rulesfn.IsValidHostLabel(_ParsedArn.Region, false) {
											if _ParsedArn.Region == _Region {
												if rulesfn.IsValidHostLabel(_ParsedArn.AccountId, false) {
													uriString := func() string {
														var out strings.Builder
														out.WriteString("https://")
														out.WriteString(_ParsedArn.AccountId)
														out.WriteString(".ddb.")
														out.WriteString(_Region)
														out.WriteString(".")
														out.WriteString(_PartitionResult.DnsSuffix)
														return out.String()
													}()

													uri, err := url.Parse(uriString)
													if err != nil {
														return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
													}

													return smithyendpoints.Endpoint{
														URI:     *uri,
														Headers: http.Header{},
														Properties: func() smithy.Properties {
															var out smithy.Properties
															out.Set("metricValues", []interface{}{
																"O",
															})
															return out
														}(),
													}, nil
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
			if exprVal := params.AccountIdEndpointMode; exprVal != nil {
				_AccountIdEndpointMode := *exprVal
				_ = _AccountIdEndpointMode
				if !(_AccountIdEndpointMode == "disabled") {
					if _PartitionResult.Name == "aws" {
						if !(_UseFIPS == true) {
							if exprVal := params.ResourceArnList; exprVal != nil {
								_ResourceArnList := stringSlice(exprVal)
								_ = _ResourceArnList
								if exprVal := _ResourceArnList.Get(0); exprVal != nil {
									_FirstArn := *exprVal
									_ = _FirstArn
									if exprVal := awsrulesfn.ParseARN(_FirstArn); exprVal != nil {
										_ParsedArn := *exprVal
										_ = _ParsedArn
										if _ParsedArn.Service == "dynamodb" {
											if rulesfn.IsValidHostLabel(_ParsedArn.Region, false) {
												if _ParsedArn.Region == _Region {
													if rulesfn.IsValidHostLabel(_ParsedArn.AccountId, false) {
														uriString := func() string {
															var out strings.Builder
															out.WriteString("https://")
															out.WriteString(_ParsedArn.AccountId)
															out.WriteString(".ddb.")
															out.WriteString(_Region)
															out.WriteString(".")
															out.WriteString(_PartitionResult.DnsSuffix)
															return out.String()
														}()

														uri, err := url.Parse(uriString)
														if err != nil {
															return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
														}

														return smithyendpoints.Endpoint{
															URI:     *uri,
															Headers: http.Header{},
															Properties: func() smithy.Properties {
																var out smithy.Properties
																out.Set("metricValues", []interface{}{
																	"O",
																})
																return out
															}(),
														}, nil
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
			if exprVal := params.AccountIdEndpointMode; exprVal != nil {
				_AccountIdEndpointMode := *exprVal
				_ = _AccountIdEndpointMode
				if !(_AccountIdEndpointMode == "disabled") {
					if _PartitionResult.Name == "aws" {
						if !(_UseFIPS == true) {
							if exprVal := params.AccountId; exprVal != nil {
								_AccountId := *exprVal
								_ = _AccountId
								if rulesfn.IsValidHostLabel(_AccountId, false) {
									uriString := func() string {
										var out strings.Builder
										out.WriteString("https://")
										out.WriteString(_AccountId)
										out.WriteString(".ddb.")
										out.WriteString(_Region)
										out.WriteString(".")
										out.WriteString(_PartitionResult.DnsSuffix)
										return out.String()
									}()

									uri, err := url.Parse(uriString)
									if err != nil {
										return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
									}

									return smithyendpoints.Endpoint{
										URI:     *uri,
										Headers: http.Header{},
										Properties: func() smithy.Properties {
											var out smithy.Properties
											out.Set("metricValues", []interface{}{
												"O",
											})
											return out
										}(),
									}, nil
								}
								return endpoint, fmt.Errorf("endpoint rule error, %s", "Credentials-sourced account ID parameter is invalid")
							}
						}
					}
				}
			}
			if exprVal := params.AccountIdEndpointMode; exprVal != nil {
				_AccountIdEndpointMode := *exprVal
				_ = _AccountIdEndpointMode
				if _AccountIdEndpointMode == "required" {
					if !(_UseFIPS == true) {
						if _PartitionResult.Name == "aws" {
							return endpoint, fmt.Errorf("endpoint rule error, %s", "AccountIdEndpointMode is required but no AccountID was provided or able to be loaded")
						}
						return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: AccountIdEndpointMode is required but account endpoints are not supported in this partition")
					}
					return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: AccountIdEndpointMode is required and FIPS is enabled, but FIPS account endpoints are not supported")
				}
			}
			uriString := func() string {
				var out strings.Builder
				out.WriteString("https://dynamodb.")
				out.WriteString(_Region)
				out.WriteString(".")
				out.WriteString(_PartitionResult.DnsSuffix)
				return out.String()
			}()

			uri, err := url.Parse(uriString)
			if err != nil {
				return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString)
			}

			return smithyendpoints.Endpoint{
				URI:     *uri,
				Headers: http.Header{},
			}, nil
		}
		return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.")
	}
	return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region")
}

type endpointParamsBinder interface {
	bindEndpointParams(*EndpointParameters)
}

func bindEndpointParams(ctx context.Context, input interface{}, options Options) (*EndpointParameters, error) {
	params := &EndpointParameters{}

	region, err := bindRegion(options.Region)
	if err != nil {
		return nil, err
	}
	params.Region = region

	params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled)
	params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled)
	params.Endpoint = options.BaseEndpoint
	params.AccountId = resolveAccountID(getIdentity(ctx), options.AccountIDEndpointMode)
	params.AccountIdEndpointMode = aws.String(string(options.AccountIDEndpointMode))

	if b, ok := input.(endpointParamsBinder); ok {
		b.bindEndpointParams(params)
	}

	return params, nil
}

type resolveEndpointV2Middleware struct {
	options Options
}

func (*resolveEndpointV2Middleware) ID() string {
	return "ResolveEndpointV2"
}

func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) (
	out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
) {
	_, span := tracing.StartSpan(ctx, "ResolveEndpoint")
	defer span.End()

	if awsmiddleware.GetRequiresLegacyEndpoints(ctx) {
		return next.HandleFinalize(ctx, in)
	}

	if err := checkAccountID(getIdentity(ctx), m.options.AccountIDEndpointMode); err != nil {
		return out, metadata, fmt.Errorf("invalid accountID set: %w", err)
	}

	req, ok := in.Request.(*smithyhttp.Request)
	if !ok {
		return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
	}

	if m.options.EndpointResolverV2 == nil {
		return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil")
	}

	params, err := bindEndpointParams(ctx, getOperationInput(ctx), m.options)
	if err != nil {
		return out, metadata, fmt.Errorf("failed to bind endpoint params, %w", err)
	}
	endpt, err := timeOperationMetric(ctx, "client.call.resolve_endpoint_duration",
		func() (smithyendpoints.Endpoint, error) {
			return m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params)
		})
	if err != nil {
		return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err)
	}

	span.SetProperty("client.call.resolved_endpoint", endpt.URI.String())

	if endpt.URI.RawPath == "" && req.URL.RawPath != "" {
		endpt.URI.RawPath = endpt.URI.Path
	}
	req.URL.Scheme = endpt.URI.Scheme
	req.URL.Host = endpt.URI.Host
	req.URL.Path = smithyhttp.JoinPath(endpt.URI.Path, req.URL.Path)
	req.URL.RawPath = smithyhttp.JoinPath(endpt.URI.RawPath, req.URL.RawPath)
	for k := range endpt.Headers {
		req.Header.Set(k, endpt.Headers.Get(k))
	}

	rscheme := getResolvedAuthScheme(ctx)
	if rscheme == nil {
		return out, metadata, fmt.Errorf("no resolved auth scheme")
	}

	opts, _ := smithyauth.GetAuthOptions(&endpt.Properties)
	for _, o := range opts {
		rscheme.SignerProperties.SetAll(&o.SignerProperties)
	}

	span.End()
	return next.HandleFinalize(ctx, in)
}
