// Path: src/main/java/com/webfluxclient/metadata/request/RequestHeader.java
// public interface RequestHeader {
//     String getName();
// 
//     List<String> getValues(Map<String, List<String>> parameterValues);
// 
//     @EqualsAndHashCode
//     class BasicRequestHeader implements RequestHeader {
// 
//         private String name;
//         private String value;
// 
//         public BasicRequestHeader(String name, String value) {
//             this.name = name;
//             this.value = value;
//         }
// 
//         @Override
//         public String getName() {
//             return name;
//         }
// 
//         @Override
//         public List<String> getValues(Map<String, List<String>> parameterValues) {
//             return Collections.singletonList(value);
//         }
//     }
// 
//     @EqualsAndHashCode
//     class DynamicRequestHeader implements RequestHeader {
// 
//         private String name;
// 
//         public DynamicRequestHeader(String name) {
//             this.name = name;
//         }
// 
//         @Override
//         public String getName() {
//             return name;
//         }
// 
//         @Override
//         public List<String> getValues(Map<String, List<String>> parameterValues) {
//             return parameterValues.getOrDefault(name, Collections.emptyList());
//         }
// 
//     }
// }
// 
// Path: src/main/java/com/webfluxclient/metadata/request/RequestHeaders.java
// public class RequestHeaders {
//     private ParameterEncoder parameterEncoder;
//     private Map<String, RequestHeader> headers;
//     private Map<Integer, String> indexToName;
// 
//     public RequestHeaders(Map<String, RequestHeader> headers, Map<Integer, String> indexToName) {
//         this.parameterEncoder = ParameterEncoder.create(false);
//         this.headers = unmodifiableMap(headers);
//         this.indexToName = unmodifiableMap(indexToName);
//     }
// 
//     public Map<String, RequestHeader> getHeaders() {
//         return headers;
//     }
// 
//     public Map<Integer, String> getIndexToName() {
//         return indexToName;
//     }
// 
//     public HttpHeaders encode(Object[] parameterValues) {
//         Map<String, List<String>> headerDynamicValue = parameterEncoder.convertToListOfString(indexToName, parameterValues);
//         HttpHeaders httpHeaders = new HttpHeaders();
//         for (RequestHeader header : headers.values()) {
//             List<String> headerValues = header.getValues(headerDynamicValue);
//             if (!headerValues.isEmpty()) {
//                 httpHeaders.put(header.getName(), headerValues);
//             }
//         }
//         return httpHeaders;
//     }
// }
// 
// Path: src/main/java/com/webfluxclient/metadata/request/RequestTemplate.java
// @Getter
// @AllArgsConstructor
// public class RequestTemplate {
//     private UriBuilder uriBuilder;
//     private HttpMethod httpMethod;
//     private RequestHeaders requestHeaders;
//     private Integer bodyIndex;
//     private ResolvableType requestBodyType;
//     private MultiValueMap<Integer, String> variableIndexToName;
// 
//     public Request apply(Object[] args) {
//         return new DefaultRequest(uriBuilder,
//                 httpMethod,
//                 requestHeaders.encode(args),
//                 nameToVariable(args),
//                 buildBody(args));
//     }
// 
//     private BodyInserter<?, ? super ClientHttpRequest> buildBody(Object[] args) {
//         if (bodyIndex == null) {
//             return BodyInserters.empty();
//         }
//         
//         Object body = args[bodyIndex];
//         if (isDataBufferPublisher(requestBodyType)) {
//             return BodyInserters.fromDataBuffers((Publisher<DataBuffer>) body);
//         } else if (isPublisher(requestBodyType)) {
//             return BodyInserters.fromPublisher((Publisher) body, requestBodyType.getGeneric(0).getRawClass());
//         } else if (isResource(requestBodyType)) {
//             return BodyInserters.fromResource((Resource) body);
//         } else if (isFormData(requestBodyType)) {
//             return BodyInserters.fromFormData((MultiValueMap<String, String>) body);
//         } else {
//             return BodyInserters.fromObject(body);
//         }
//     }
//     
//     private Map<String, Object> nameToVariable(Object[] args) {
//         Map<String, Object> nameToVariable = new HashMap<>();
//         variableIndexToName.forEach((variableIndex, variableNames) -> {
//             variableNames
//                     .forEach(variableName -> nameToVariable.put(variableName, args[variableIndex]));
//         });
//         return nameToVariable;
//     }
// }


import com.webfluxclient.metadata.request.RequestHeader;
import com.webfluxclient.metadata.request.RequestHeaders;
import com.webfluxclient.metadata.request.RequestTemplate;
import lombok.Getter;
import org.springframework.core.ResolvableType;
import org.springframework.http.HttpMethod;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.springframework.web.util.UriBuilder;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
package com.webfluxclient.metadata;



@Getter
public class MethodMetadata {
    private Method targetMethod;
    private ResolvableType responseBodyType;
    private RequestTemplate requestTemplate;
    
    private MethodMetadata(Builder builder) {
        targetMethod = builder.targetMethod;
        responseBodyType = builder.returnType;
        requestTemplate = new RequestTemplate(
                builder.uriBuilder,
                builder.httpMethod,
// Path: src/main/java/com/webfluxclient/metadata/request/RequestHeader.java
// public interface RequestHeader {
//     String getName();
// 
//     List<String> getValues(Map<String, List<String>> parameterValues);
// 
//     @EqualsAndHashCode
//     class BasicRequestHeader implements RequestHeader {
// 
//         private String name;
//         private String value;
// 
//         public BasicRequestHeader(String name, String value) {
//             this.name = name;
//             this.value = value;
//         }
// 
//         @Override
//         public String getName() {
//             return name;
//         }
// 
//         @Override
//         public List<String> getValues(Map<String, List<String>> parameterValues) {
//             return Collections.singletonList(value);
//         }
//     }
// 
//     @EqualsAndHashCode
//     class DynamicRequestHeader implements RequestHeader {
// 
//         private String name;
// 
//         public DynamicRequestHeader(String name) {
//             this.name = name;
//         }
// 
//         @Override
//         public String getName() {
//             return name;
//         }
// 
//         @Override
//         public List<String> getValues(Map<String, List<String>> parameterValues) {
//             return parameterValues.getOrDefault(name, Collections.emptyList());
//         }
// 
//     }
// }
// 
// Path: src/main/java/com/webfluxclient/metadata/request/RequestHeaders.java
// public class RequestHeaders {
//     private ParameterEncoder parameterEncoder;
//     private Map<String, RequestHeader> headers;
//     private Map<Integer, String> indexToName;
// 
//     public RequestHeaders(Map<String, RequestHeader> headers, Map<Integer, String> indexToName) {
//         this.parameterEncoder = ParameterEncoder.create(false);
//         this.headers = unmodifiableMap(headers);
//         this.indexToName = unmodifiableMap(indexToName);
//     }
// 
//     public Map<String, RequestHeader> getHeaders() {
//         return headers;
//     }
// 
//     public Map<Integer, String> getIndexToName() {
//         return indexToName;
//     }
// 
//     public HttpHeaders encode(Object[] parameterValues) {
//         Map<String, List<String>> headerDynamicValue = parameterEncoder.convertToListOfString(indexToName, parameterValues);
//         HttpHeaders httpHeaders = new HttpHeaders();
//         for (RequestHeader header : headers.values()) {
//             List<String> headerValues = header.getValues(headerDynamicValue);
//             if (!headerValues.isEmpty()) {
//                 httpHeaders.put(header.getName(), headerValues);
//             }
//         }
//         return httpHeaders;
//     }
// }
// 
// Path: src/main/java/com/webfluxclient/metadata/request/RequestTemplate.java
// @Getter
// @AllArgsConstructor
// public class RequestTemplate {
//     private UriBuilder uriBuilder;
//     private HttpMethod httpMethod;
//     private RequestHeaders requestHeaders;
//     private Integer bodyIndex;
//     private ResolvableType requestBodyType;
//     private MultiValueMap<Integer, String> variableIndexToName;
// 
//     public Request apply(Object[] args) {
//         return new DefaultRequest(uriBuilder,
//                 httpMethod,
//                 requestHeaders.encode(args),
//                 nameToVariable(args),
//                 buildBody(args));
//     }
// 
//     private BodyInserter<?, ? super ClientHttpRequest> buildBody(Object[] args) {
//         if (bodyIndex == null) {
//             return BodyInserters.empty();
//         }
//         
//         Object body = args[bodyIndex];
//         if (isDataBufferPublisher(requestBodyType)) {
//             return BodyInserters.fromDataBuffers((Publisher<DataBuffer>) body);
//         } else if (isPublisher(requestBodyType)) {
//             return BodyInserters.fromPublisher((Publisher) body, requestBodyType.getGeneric(0).getRawClass());
//         } else if (isResource(requestBodyType)) {
//             return BodyInserters.fromResource((Resource) body);
//         } else if (isFormData(requestBodyType)) {
//             return BodyInserters.fromFormData((MultiValueMap<String, String>) body);
//         } else {
//             return BodyInserters.fromObject(body);
//         }
//     }
//     
//     private Map<String, Object> nameToVariable(Object[] args) {
//         Map<String, Object> nameToVariable = new HashMap<>();
//         variableIndexToName.forEach((variableIndex, variableNames) -> {
//             variableNames
//                     .forEach(variableName -> nameToVariable.put(variableName, args[variableIndex]));
//         });
//         return nameToVariable;
//     }
// }


// Path: src/main/java/com/webfluxclient/metadata/MethodMetadata.java
import com.webfluxclient.metadata.request.RequestHeader;
import com.webfluxclient.metadata.request.RequestHeaders;
import com.webfluxclient.metadata.request.RequestTemplate;
import lombok.Getter;
import org.springframework.core.ResolvableType;
import org.springframework.http.HttpMethod;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.util.DefaultUriBuilderFactory;
import org.springframework.web.util.UriBuilder;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;

package com.webfluxclient.metadata;



@Getter
public class MethodMetadata {
    private Method targetMethod;
    private ResolvableType responseBodyType;
    private RequestTemplate requestTemplate;
    
    private MethodMetadata(Builder builder) {
        targetMethod = builder.targetMethod;
        responseBodyType = builder.returnType;
        requestTemplate = new RequestTemplate(
                builder.uriBuilder,
                builder.httpMethod,
                new RequestHeaders(builder.headers, builder.headerIndexToName),