package http

import (
	
	

	
)

const contentMD5Header = "Content-Md5"

// contentMD5Checksum provides a middleware to compute and set
// content-md5 checksum for a http request
type contentMD5Checksum struct {
}

// AddContentChecksumMiddleware adds checksum middleware to middleware's
// build step.
func ( *middleware.Stack) error {
	// This middleware must be executed before request body is set.
	return .Build.Add(&contentMD5Checksum{}, middleware.Before)
}

// ID returns the identifier for the checksum middleware
func ( *contentMD5Checksum) () string { return "ContentChecksum" }

// HandleBuild adds behavior to compute md5 checksum and add content-md5 header
// on http request
func ( *contentMD5Checksum) (
	 context.Context,  middleware.BuildInput,  middleware.BuildHandler,
) (
	 middleware.BuildOutput,  middleware.Metadata,  error,
) {
	,  := .Request.(*Request)
	if ! {
		return , , fmt.Errorf("unknown request type %T", )
	}

	// if Content-MD5 header is already present, return
	if  := .Header.Get(contentMD5Header); len() != 0 {
		return .HandleBuild(, )
	}

	// fetch the request stream.
	 := .GetStream()
	// compute checksum if payload is explicit
	if  != nil {
		if !.IsStreamSeekable() {
			return , , fmt.Errorf(
				"unseekable stream is not supported for computing md5 checksum")
		}

		,  := computeMD5Checksum()
		if  != nil {
			return , , fmt.Errorf("error computing md5 checksum, %w", )
		}

		// reset the request stream
		if  := .RewindStream();  != nil {
			return , , fmt.Errorf(
				"error rewinding request stream after computing md5 checksum, %w", )
		}

		// set the 'Content-MD5' header
		.Header.Set(contentMD5Header, string())
	}

	// set md5 header value
	return .HandleBuild(, )
}