package cd.casic.plugin.core;

import org.springframework.util.*;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @description: TODO
 * @author: mianbin
 * @date: 2025/5/13 10:35
 * @version: 1.0
 */
public class PluginRequestMappingHandlerMapping extends RequestMappingHandlerMapping {

    private final MultiValueMap<String, RequestMappingInfo> pluginMappingInfo =
            new LinkedMultiValueMap<>();

    @Override
    protected void initHandlerMethods() {
    }

    public void registerHandlerMethods(String pluginId, Object handler) {

    }

    private String formatMappings(Class<?> userType, Map<Method, RequestMappingInfo> methods) {
        String packageName = ClassUtils.getPackageName(userType);
        String formattedType = (StringUtils.hasText(packageName)
                ? Arrays.stream(packageName.split("\\."))
                .map(packageSegment -> packageSegment.substring(0, 1))
                .collect(Collectors.joining(".", "", "." + userType.getSimpleName())) :
                userType.getSimpleName());
        Function<Method, String> methodFormatter =
                method -> Arrays.stream(method.getParameterTypes())
                        .map(Class::getSimpleName)
                        .collect(Collectors.joining(",", "(", ")"));
        return methods.entrySet().stream()
                .map(e -> {
                    Method method = e.getKey();
                    return e.getValue() + ": " + method.getName() + methodFormatter.apply(method);
                })
                .collect(Collectors.joining("\n\t", "\n\t" + formattedType + ":" + "\n\t", ""));
    }

    public void unregister(String pluginId) {
        Assert.notNull(pluginId, "The pluginId must not be null.");
        if (!pluginMappingInfo.containsKey(pluginId)) {
            return;
        }
        pluginMappingInfo.remove(pluginId).forEach(this::unregisterMapping);
    }

    protected List<RequestMappingInfo> getMappings(String pluginId) {
        List<RequestMappingInfo> requestMappingInfos = pluginMappingInfo.get(pluginId);
        if (requestMappingInfos == null) {
            return Collections.emptyList();
        }
        return List.copyOf(requestMappingInfos);
    }
}

