package http

import (
	
	

	
)

type isContentTypeAutoSet struct{}

// SetIsContentTypeDefaultValue returns a Context specifying if the request's
// content-type header was set to a default value.
func ( context.Context,  bool) context.Context {
	return context.WithValue(, isContentTypeAutoSet{}, )
}

// GetIsContentTypeDefaultValue returns if the content-type HTTP header on the
// request is a default value that was auto assigned by an operation
// serializer. Allows middleware post serialization to know if the content-type
// was auto set to a default value or not.
//
// Also returns false if the Context value was never updated to include if
// content-type was set to a default value.
func ( context.Context) bool {
	,  := .Value(isContentTypeAutoSet{}).(bool)
	return 
}

// AddNoPayloadDefaultContentTypeRemover Adds the DefaultContentTypeRemover
// middleware to the stack after the operation serializer. This middleware will
// remove the content-type header from the request if it was set as a default
// value, and no request payload is present.
//
// Returns error if unable to add the middleware.
func ( *middleware.Stack) ( error) {
	 = .Serialize.Insert(removeDefaultContentType{},
		"OperationSerializer", middleware.After)
	if  != nil {
		return fmt.Errorf("failed to add %s serialize middleware, %w",
			removeDefaultContentType{}.ID(), )
	}

	return nil
}

// RemoveNoPayloadDefaultContentTypeRemover removes the
// DefaultContentTypeRemover middleware from the stack. Returns an error if
// unable to remove the middleware.
func ( *middleware.Stack) ( error) {
	_,  = .Serialize.Remove(removeDefaultContentType{}.ID())
	if  != nil {
		return fmt.Errorf("failed to remove %s serialize middleware, %w",
			removeDefaultContentType{}.ID(), )

	}
	return nil
}

// removeDefaultContentType provides after serialization middleware that will
// remove the content-type header from an HTTP request if the header was set as
// a default value by the operation serializer, and there is no request payload.
type removeDefaultContentType struct{}

// ID returns the middleware ID
func (removeDefaultContentType) () string { return "RemoveDefaultContentType" }

// HandleSerialize implements the serialization middleware.
func (removeDefaultContentType) (
	 context.Context,  middleware.SerializeInput,  middleware.SerializeHandler,
) (
	 middleware.SerializeOutput,  middleware.Metadata,  error,
) {
	,  := .Request.(*Request)
	if ! {
		return , , fmt.Errorf(
			"unexpected request type %T for removeDefaultContentType middleware",
			.Request)
	}

	if GetIsContentTypeDefaultValue() && .GetStream() == nil {
		.Header.Del("Content-Type")
		.Request = 
	}

	return .HandleSerialize(, )
}

type headerValue struct {
	header string
	value  string
	append bool
}

type headerValueHelper struct {
	headerValues []headerValue
}

func ( *headerValueHelper) ( headerValue) {
	.headerValues = append(.headerValues, )
}

func ( *headerValueHelper) () string {
	return "HTTPHeaderHelper"
}

func ( *headerValueHelper) ( context.Context,  middleware.BuildInput,  middleware.BuildHandler) ( middleware.BuildOutput,  middleware.Metadata,  error) {
	,  := .Request.(*Request)
	if ! {
		return , , fmt.Errorf("unknown transport type %T", .Request)
	}

	for ,  := range .headerValues {
		if .append {
			.Header.Add(.header, .value)
		} else {
			.Header.Set(.header, .value)
		}
	}

	return .HandleBuild(, )
}

func ( *middleware.Stack) (*headerValueHelper, error) {
	 := (*headerValueHelper)(nil).ID()
	,  := .Build.Get()
	if ! {
		 = &headerValueHelper{}
		 := .Build.Add(, middleware.After)
		if  != nil {
			return nil, 
		}
	}

	,  := .(*headerValueHelper)
	if ! {
		return nil, fmt.Errorf("%T for %s middleware did not match expected type", , )
	}

	return , nil
}

// AddHeaderValue returns a stack mutator that adds the header value pair to header.
// Appends to any existing values if present.
func ( string,  string) func( *middleware.Stack) error {
	return func( *middleware.Stack) error {
		,  := getOrAddHeaderValueHelper()
		if  != nil {
			return 
		}
		.addHeaderValue(headerValue{header: , value: , append: true})
		return nil
	}
}

// SetHeaderValue returns a stack mutator that adds the header value pair to header.
// Replaces any existing values if present.
func ( string,  string) func( *middleware.Stack) error {
	return func( *middleware.Stack) error {
		,  := getOrAddHeaderValueHelper()
		if  != nil {
			return 
		}
		.addHeaderValue(headerValue{header: , value: , append: false})
		return nil
	}
}