package runtime

import (
	
	
	
	
	
	
	
	

	
)

const tagName = "json"
const jsonContentType = "application/json"

type RequestBodyEncoding struct {
	ContentType string
	Style       string
	Explode     *bool
	Required    *bool
}

func ( interface{},  multipart.Reader) error {
	const  = 32 << 20
	,  := .ReadForm()
	if  != nil {
		return 
	}
	return BindForm(, .Value, .File, nil)
}

func ( interface{},  map[string][]string,  map[string][]*multipart.FileHeader,  map[string]RequestBodyEncoding) error {
	 := reflect.Indirect(reflect.ValueOf())
	if .Kind() != reflect.Struct {
		return errors.New("form data body should be a struct")
	}
	 := .Type()

	for  := 0;  < .NumField(); ++ {
		 := .Field()
		 := .Field().Tag.Get(tagName)
		if !.CanInterface() ||  == "-" {
			continue
		}
		 = strings.Split(, ",")[0] // extract the name of the tag
		if ,  := [];  {
			// custom encoding
			 := []
			if len() == 0 {
				continue
			}
			 := [0]
			if .ContentType != "" {
				if strings.HasPrefix(.ContentType, jsonContentType) {
					if  := json.Unmarshal([]byte(), );  != nil {
						return 
					}
				}
				return errors.New("unsupported encoding, only application/json is supported")
			} else {
				var  bool
				if .Explode != nil {
					 = *.Explode
				}
				var  bool
				if .Required != nil {
					 = *.Required
				}
				if  := BindStyledParameterWithOptions(.Style, , , .Addr().Interface(), BindStyledParameterOptions{
					ParamLocation: ParamLocationUndefined,
					Explode:       ,
					Required:      ,
				});  != nil {
					return 
				}
			}
		} else {
			// regular form data
			if ,  := bindFormImpl(, , , );  != nil {
				return 
			}
		}
	}

	return nil
}

func ( interface{},  map[string]RequestBodyEncoding) (url.Values, error) {
	 := reflect.Indirect(reflect.ValueOf())
	if .Kind() != reflect.Struct {
		return nil, errors.New("form data body should be a struct")
	}
	 := .Type()
	 := make(url.Values)
	for  := 0;  < .NumField(); ++ {
		 := .Field()
		 := .Field().Tag.Get(tagName)
		if !.CanInterface() ||  == "-" {
			continue
		}
		 := strings.HasSuffix(, ",omitempty")
		if  && .IsZero() {
			continue
		}
		 = strings.Split(, ",")[0] // extract the name of the tag
		if ,  := [];  && .ContentType != "" {
			if strings.HasPrefix(.ContentType, jsonContentType) {
				if ,  := json.Marshal();  != nil { //nolint:staticcheck
					return nil, 
				} else {
					[] = append([], string())
				}
			}
			return nil, errors.New("unsupported encoding, only application/json is supported")
		} else {
			marshalFormImpl(, , )
		}
	}
	return , nil
}

func ( reflect.Value,  map[string][]string,  map[string][]*multipart.FileHeader,  string) (bool, error) {
	var  bool
	switch .Kind() {
	case reflect.Interface:
		return (.Elem(), , , )
	case reflect.Ptr:
		 := .Elem()
		if !.IsValid() {
			 = reflect.New(.Type().Elem())
		}
		,  := (, , , )
		if  == nil &&  && !.Elem().IsValid() {
			.Set()
		}
		return , 
	case reflect.Slice:
		if  := append([], [+"[]"]...); len() != 0 {
			if ,  := .Interface().([]types.File);  {
				 := make([]types.File, len())
				for ,  := range  {
					[].InitFromMultipart()
				}
				.Set(reflect.ValueOf())
				 = true
			}
		}
		 := indexedElementsCount(, , )
		 := append([], [+"[]"]...)
		if +len() != 0 {
			 := reflect.MakeSlice(.Type(), +len(), +len())
			for  := 0;  < ; ++ {
				if ,  := (.Index(), , , fmt.Sprintf("%s[%v]", , ));  != nil {
					return false, 
				}
			}
			for ,  := range  {
				if  := BindStringToObject(, .Index(+).Addr().Interface());  != nil {
					return false, 
				}
			}
			.Set()
			 = true
		}
	case reflect.Struct:
		if  := []; len() != 0 {
			if ,  := .Interface().(types.File);  {
				.InitFromMultipart([0])
				.Set(reflect.ValueOf())
				return true, nil
			}
		}
		for  := 0;  < .NumField(); ++ {
			 := .Type().Field()
			 := .Tag.Get(tagName)
			if .Name == "AdditionalProperties" && .Type.Kind() == reflect.Map &&  == "-" {
				,  := bindAdditionalProperties(.Field(), , , , )
				if  != nil {
					return false, 
				}
				 =  || 
			}
			if !.Field().CanInterface() ||  == "-" {
				continue
			}
			 = strings.Split(, ",")[0] // extract the name of the tag
			,  := (.Field(), , , fmt.Sprintf("%s[%s]", , ))
			if  != nil {
				return false, 
			}
			 =  || 
		}
		return , nil
	default:
		 := []
		if len() != 0 {
			return true, BindStringToObject([0], .Addr().Interface())
		}
	}
	return , nil
}

func ( map[string][]string,  map[string][]*multipart.FileHeader,  string) int {
	 += "["
	 := -1
	for  := range  {
		if strings.HasPrefix(, ) {
			 := strings.TrimPrefix(, )
			 = [:strings.Index(, "]")]
			if ,  := strconv.Atoi();  == nil {
				if  >  {
					 = 
				}
			}
		}
	}
	for  := range  {
		if strings.HasPrefix(, ) {
			 := strings.TrimPrefix(, )
			 = [:strings.Index(, "]")]
			if ,  := strconv.Atoi();  == nil {
				if  >  {
					 = 
				}
			}
		}
	}
	return  + 1
}

func ( reflect.Value,  reflect.Value,  map[string][]string,  map[string][]*multipart.FileHeader,  string) (bool, error) {
	 := false
	 := .Type().Elem()

	// store all fixed properties in a set
	 := make(map[string]struct{})
	for  := 0;  < .NumField(); ++ {
		 := .Type().Field().Tag.Get(tagName)
		if !.Field().CanInterface() ||  == "-" {
			continue
		}
		 = strings.Split(, ",")[0]
		[] = struct{}{}
	}

	 := reflect.MakeMap(.Type())
	for  := range  {
		if strings.HasPrefix(, +"[") {
			 := strings.TrimPrefix(, +"[")
			 = [:strings.Index(, "]")]
			if ,  := [];  {
				continue
			}
			 := reflect.New()
			,  := bindFormImpl(, , , fmt.Sprintf("%s[%s]", , ))
			if  != nil {
				return false, 
			}
			.SetMapIndex(reflect.ValueOf(), .Elem())
			 =  || 
		}
	}
	for  := range  {
		if strings.HasPrefix(, +"[") {
			 := strings.TrimPrefix(, +"[")
			 = [:strings.Index(, "]")]
			if ,  := [];  {
				continue
			}
			 := reflect.New()
			.SetMapIndex(reflect.ValueOf(), )
			,  := bindFormImpl(, , , fmt.Sprintf("%s[%s]", , ))
			if  != nil {
				return false, 
			}
			.SetMapIndex(reflect.ValueOf(), .Elem())
			 =  || 
		}
	}
	if  {
		.Set()
	}
	return , nil
}

func ( reflect.Value,  url.Values,  string) {
	switch .Kind() {
	case reflect.Interface, reflect.Ptr:
		(.Elem(), , )
	case reflect.Slice:
		for  := 0;  < .Len(); ++ {
			 := .Index()
			(, , fmt.Sprintf("%s[%v]", , ))
		}
	case reflect.Struct:
		for  := 0;  < .NumField(); ++ {
			 := .Type().Field()
			 := .Tag.Get(tagName)
			if .Name == "AdditionalProperties" &&  == "-" {
				 := .MapRange()
				for .Next() {
					(.Value(), , fmt.Sprintf("%s[%s]", , .Key().String()))
				}
				continue
			}
			if !.Field().CanInterface() ||  == "-" {
				continue
			}
			 = strings.Split(, ",")[0] // extract the name of the tag
			(.Field(), , fmt.Sprintf("%s[%s]", , ))
		}
	default:
		[] = append([], fmt.Sprint(.Interface()))
	}
}