package com.github.bingoohuang.springrest.boot.resolver;

import com.github.bingoohuang.utils.codec.Json;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.annotation.RequestParamMethodArgumentResolver;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class HiRequestParamMethodArgumentResolver extends RequestParamMethodArgumentResolver {
    public HiRequestParamMethodArgumentResolver(boolean useDefaultResolution) {
        super(useDefaultResolution);
    }

    public HiRequestParamMethodArgumentResolver(ConfigurableBeanFactory beanFactory, boolean useDefaultResolution) {
        super(beanFactory, useDefaultResolution);
    }

    @Override
    protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest webRequest) throws Exception {
        Object arg = super.resolveName(name, parameter, webRequest);
        if (arg instanceof String) {
            try {
                Object obj = tryUnJson(parameter, (String) arg);
                if (obj != null) return obj;
            } catch (Throwable e) {
                // ignore
            }
        }

        return arg;
    }

    private Object tryUnJson(MethodParameter parameter, String str) {
        char c = str.charAt(0);
        boolean maybeJson = c == '{';
        boolean maybeJsonArray = c == '[';
        Object obj = null;
        if (maybeJson) {
            obj = Json.unJson(str, parameter.getParameterType());
        } else if (maybeJsonArray) {
            Type genericParameterType = parameter.getGenericParameterType();
            boolean isGeneric = genericParameterType instanceof ParameterizedType;
            if (isGeneric) {
                ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
                Class<?> argType = (Class) parameterizedType.getActualTypeArguments()[0];

                obj = Json.unJsonArray(str, argType);
            }
        }
        return obj;
    }
}

@@ -99,16 +99,64 @@
 c.Json;%0A
+import com.google.common.primitives.Primitives;%0A
 import o
@@ -1454,29 +1454,60 @@
     
-char c = str.charAt(0
+Class%3C?%3E parameterType = parameter.getParameterType(
 );%0A 
@@ -1509,32 +1509,29 @@
 ();%0A        
-boolean 
+if (!
 maybeJson = 
@@ -1531,89 +1531,279 @@
 Json
- = c == '%7B';%0A        boolean maybeJsonArray = c == '%5B';%0A        Object obj = null
+Type(parameterType)) return null;%0A%0A        return tryParseAsJson(parameter, str, parameterType);%0A    %7D%0A%0A    private Object tryParseAsJson(MethodParameter parameter, String str, Class%3C?%3E parameterType) %7B%0A        char c = str.charAt(0);%0A        boolean maybeJson = c == '%7B'
 ;%0A  
@@ -1829,37 +1829,38 @@
 ) %7B%0A            
-obj =
+return
  Json.unJson(str
@@ -1870,35 +1870,20 @@
 arameter
-.getParameter
 Type
-()
 );%0A     
@@ -1890,13 +1890,60 @@
    %7D
- else
+%0A%0A        boolean maybeJsonArray = c == '%5B';%0A       
  if 
@@ -2353,21 +2353,22 @@
         
-obj =
+return
  Json.un
@@ -2427,25 +2427,315 @@
      return 
-obj
+null;%0A    %7D%0A%0A    private boolean maybeJsonType(Class%3C?%3E parameterType) %7B%0A        if (parameterType.isPrimitive()) return false;%0A        if (Primitives.isWrapperType(parameterType)) return false;%0A        if (CharSequence.class.isAssignableFrom(parameterType)) return false;%0A%0A        return true
 ;%0A    %7D%0A%7D%0A

enhance HiRequestParamMethodArgumentResolver