package com.lnwazg.httpkit.client.rpc;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.lnwazg.kit.gson.GsonKit;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

/**
 * 基于Http的rpc客户端
 * @author nan.li
 * @version 2019年9月2日
 */
public class HttpRpc
{
    /**
    * 单线程的线程池
    */
    public static ExecutorService singleExec = Executors.newSingleThreadExecutor();
    
    /**
     * 客户端列表
     */
    static Map<String, HttpRpc> clients = new HashMap<String, HttpRpc>();
    
    /**
     * 服务资源的位置
     */
    private String uri;
    
    public HttpRpc(String uri)
    {
        this.uri = uri;
    }
    
    /**
     * 使用某个位置的http服务资源
     * @author nan.li
     * @param uri
     * @return
     */
    public static HttpRpc use(String uri)
    {
        if (!clients.containsKey(uri))
        {
            clients.put(uri, new HttpRpc(uri));
        }
        return clients.get(uri);
    }
    
    /**
     * 引用某个interface，生产这个interface的访问代理工具
     * @author nan.li
     * @param interfaceClazz
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> T reference(Class<T> interfaceClazz)
    {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(interfaceClazz);//设置动态代理的父类信息
        // 回调方法
        enhancer.setCallback(createMethodInterceptor(interfaceClazz));//设置方法过滤器
        // 创建代理对象
        return (T)enhancer.create();
    }
    
    private MethodInterceptor createMethodInterceptor(Class<?> interfaceClazz)
    {
        return new MethodInterceptor()
        {
            //            obj - "this", the enhanced object   obj是生成的那个代理对象实例
            //            method - intercepted Method 
            //            args - argument array; primitive types are wrapped 
            //            proxy - used to invoke super (non-intercepted method); may be called as many times as needed 
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy)
                throws Throwable
            {
                //被代理的示例：  UserResponse processUserRequest(UserRequest userRequest);
                //1.请求参数最多只有一个。将其序列化成json
                //2.请求url的拼接方式： url + interfaceName
                //3.请求的方法为：method.getName(),放在请求头中即可
                //4.如果该method的返回类型为void，则做成异步调用（起线程）；否则做成同步调用
                //5.对于同步调用，等待调用结果（json ），然后将其返序列化成对象
                Object returnObj = null;
                //                returnObj = proxy.invokeSuper(obj, args);
                String requestUri = createRequestUri(interfaceClazz);
                String methodHead = method.getName();
                String requestParam = "";//请求体中的json参数。默认为无参数，则请求参数为空
                Class<?> returnClass = method.getReturnType();//响应的类
                if (args.length > 0)
                {
                    //方法有参数时，支持多个参数的方法调用
                    //但是不支持方法的重载
                    requestParam = GsonKit.parseObject2String(args);
                }
                if (returnClass == void.class)
                {
                    //异步调用
                    final String requestParamFinal = requestParam;
                    //在线程池中排队调用
                    singleExec.execute(() -> {
                        callHttp(requestUri, methodHead, requestParamFinal);
                    });
                }
                else
                {
                    //同步调用
                    String responseJson = callHttp(requestUri, methodHead, requestParam);
                    returnObj = GsonKit.parseString2Object(responseJson, returnClass);
                }
                return returnObj;
            }
        };
    }
    
    /**
     * 调用Http服务
     * @author nan.li
     * @param requestUri
     * @param methodHead
     * @param requestParam
     * @return
     */
    private String callHttp(String requestUri, String methodHead, String requestParam)
    {
        return null;
    }
    
    /**
     * 生成请求服务地址
     * @author nan.li
     * @param interfaceClazz
     * @return
     */
    private String createRequestUri(Class<?> interfaceClazz)
    {
        //http://127.0.0.1:8080/root/__httpRpc__/{interfaceName}
        return String.format("%s/__httpRpc__/%s", uri, interfaceClazz.getName());
    }
}

@@ -234,16 +234,56 @@
 GsonKit;
+%0Aimport com.lnwazg.kit.reflect.ClassKit;
 %0A%0Aimport
@@ -2812,38 +2812,95 @@
 ing 
-methodHead = method.getName();
+uniqueMethodName = ClassKit.getUniqueMethodName(method);//%E9%80%9A%E8%BF%87%E6%96%B9%E6%B3%95%E5%90%8D%E4%BF%A1%E6%81%AF%E7%89%B9%E6%AE%8A%E7%A0%81%E7%94%9F%E6%88%90%E5%94%AF%E4%B8%80%E6%96%B9%E6%B3%95%E5%90%8D%EF%BC%8C%E6%9D%A5%E5%AE%9E%E7%8E%B0%E6%96%B9%E6%B3%95%E5%90%8D%E7%9A%84%E2%80%9C%E9%87%8D%E8%BD%BD%E2%80%9D
 %0A   
@@ -3135,41 +3135,8 @@
 %E6%B3%95%E8%B0%83%E7%94%A8%0A
-                    //%E4%BD%86%E6%98%AF%E4%B8%8D%E6%94%AF%E6%8C%81%E6%96%B9%E6%B3%95%E7%9A%84%E9%87%8D%E8%BD%BD%0A
     
@@ -3497,34 +3497,40 @@
 requestUri, 
-m
+uniqueM
 ethod
-Head
+Name
 , requestPar
@@ -3710,26 +3710,32 @@
 estUri, 
-m
+uniqueM
 ethod
-Head
+Name
 , reques

Update HttpRpc.java