package http

import (
	
	

	
)

// ComputeContentLength provides a middleware to set the content-length
// header for the length of a serialize request body.
type ComputeContentLength struct {
}

// AddComputeContentLengthMiddleware adds ComputeContentLength to the middleware
// stack's Build step.
func ( *middleware.Stack) error {
	return .Build.Add(&ComputeContentLength{}, middleware.After)
}

// ID returns the identifier for the ComputeContentLength.
func ( *ComputeContentLength) () string { return "ComputeContentLength" }

// HandleBuild adds the length of the serialized request to the HTTP header
// if the length can be determined.
func ( *ComputeContentLength) (
	 context.Context,  middleware.BuildInput,  middleware.BuildHandler,
) (
	 middleware.BuildOutput,  middleware.Metadata,  error,
) {
	,  := .Request.(*Request)
	if ! {
		return , , fmt.Errorf("unknown request type %T", )
	}

	// do nothing if request content-length was set to 0 or above.
	if .ContentLength >= 0 {
		return .HandleBuild(, )
	}

	// attempt to compute stream length
	if , ,  := .StreamLength();  != nil {
		return , , fmt.Errorf(
			"failed getting length of request stream, %w", )
	} else if  {
		.ContentLength = 
	}

	return .HandleBuild(, )
}

// validateContentLength provides a middleware to validate the content-length
// is valid (greater than zero), for the serialized request payload.
type validateContentLength struct{}

// ValidateContentLengthHeader adds middleware that validates request content-length
// is set to value greater than zero.
func ( *middleware.Stack) error {
	return .Build.Add(&validateContentLength{}, middleware.After)
}

// ID returns the identifier for the ComputeContentLength.
func ( *validateContentLength) () string { return "ValidateContentLength" }

// HandleBuild adds the length of the serialized request to the HTTP header
// if the length can be determined.
func ( *validateContentLength) (
	 context.Context,  middleware.BuildInput,  middleware.BuildHandler,
) (
	 middleware.BuildOutput,  middleware.Metadata,  error,
) {
	,  := .Request.(*Request)
	if ! {
		return , , fmt.Errorf("unknown request type %T", )
	}

	// if request content-length was set to less than 0, return an error
	if .ContentLength < 0 {
		return , , fmt.Errorf(
			"content length for payload is required and must be at least 0")
	}

	return .HandleBuild(, )
}