package com.ag.secp.platform.spring;

import cn.hutool.core.collection.CollUtil;
import com.ag.secp.platform.common.AopTargetUtils;
import com.ag.util.HttpRequestor;
import com.ag.util.ResourceUtil;
import com.ag.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.wb.util.WebUtil;
import org.json.JSONObject;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


/**
 * Created by shaoqiang on 2017/8/17.
 */
public class BeanMange {
    /**
     * 请求对象。
     */
    public HttpServletRequest request;
    public HttpServletResponse response;
    public String bean;
    public String method;
    public Object params;
    /**
     * status配置
     * 0=部署模式, 开启定时任务, 需打开modulelink.xml中的对moduleRefreshScheduler的注释
     * 1=读取外部jar包开发模式 : pom.xml需要删除扩展工程jar, 修改扩展工程后重打jar包,不需要重启主工程
     * 每次请求直接读取jar包, 没有安装jrebel组件使用.
     * 2=不读jar包开发模式 : pom.xml需要引入扩展工程jar, 建议安装了jrebel组件才使用.
     * 3=測試單RxtAction
     */
    private String statusStr = ResourceUtil.getString("system", "status");

    public Object execute() throws Exception {
        Integer status = 1;
        if (!StrUtil.isEmpty(statusStr)){
            status = Integer.parseInt(statusStr);
        }
        JSONObject fields = WebUtil.fetch(request);
        fields.put("mainParams", params);
        Assert.notNull(bean, "请求热加载的参数bean不能为空！");
        Assert.notNull(method, "请求热加载的参数method不能为空！");
        /**
         * 1.判断传入的bean是否是主工程管理的bean, 如果能获取到bean的方法对象, 不需要再读取外部jar包, 直接反射调用并退出.
         * 2.如果status=2, 主工程也会管理扩展工程中实现Action接口的bean, 需要通过AopTargetUtils工具类获取代理类中的目标bean对象.
         */
        Object springBean = null;
        Method methodObj = null;
        if (SpringApplicationContext.isContainsMain(bean)) {
            springBean = SpringApplicationContext.getBean(bean);
            //if (!(springBean instanceof Action)) {
                methodObj = ReflectionUtils.findMethod(springBean.getClass(), method, JSONObject.class, HttpServletResponse.class, HttpServletRequest.class);
                return ReflectionUtils.invokeMethod(methodObj, springBean, fields, response, request);
            //}
        }

        //执行到以下代码, 表示目标bean在扩展工程中
        long on = System.currentTimeMillis();
        if (status == 0) {
            //部署模式
            String beanName = "moduleManageProcess";
            String defMethod = "deployModule";
            methodObj = ReflectionUtils.findMethod(SpringApplicationContext.getBean(beanName).getClass(), defMethod, JSONObject.class, HttpServletResponse.class, HttpServletRequest.class, String.class, String.class);
            return ReflectionUtils.invokeMethod(methodObj, SpringApplicationContext.getBean(beanName), fields, response, request, bean, method);
        }
        if (status == 1) {
            //读取外部jar包的开发模式
            String beanName = "moduleManageProcess";
            String defMethod = "developerForJar";
            methodObj = ReflectionUtils.findMethod(SpringApplicationContext.getBean(beanName).getClass(), defMethod, JSONObject.class, HttpServletResponse.class, HttpServletRequest.class, String.class, String.class);
            return ReflectionUtils.invokeMethod(methodObj, SpringApplicationContext.getBean(beanName), fields, response, request, bean, method);
        }
        if (status == 2) {
            String url = ResourceUtil.getString("system", "gatewayUrl");
            String service = ResourceUtil.getString("system", "defaultService");

            com.alibaba.fastjson.JSONObject map = new com.alibaba.fastjson.JSONObject();
            for (Map.Entry<String, Object> entry : fields.entrySet()) {
                if (entry.getKey().startsWith("org.springframework.web")){
                    continue;
                }
                if (entry.getKey().contains("userDesktop")){
                    continue;
                }
                map.put(entry.getKey(), entry.getValue());
            }
            if (map.containsKey("service") && !StrUtil.isEmpty(map.getString("service"))){
                service = map.getString("service");
            }
            url = StrUtil.join(url, service, "/", bean, "/", method);
            Object obj = HttpRequestor.doPost(url, map.toString(), HttpRequestor.Content_Type_JSON);
            WebUtil.send(response, obj);
        }

        long end = System.currentTimeMillis();
        //System.out.println("outside jar is run times============" + (end - on));
        return null;
    }

    public BeanMange() {
    }

    public BeanMange(HttpServletRequest request, HttpServletResponse response, String bean, String method, Object params) {
        this.request = request;
        this.response = response;
        this.bean = bean;
        this.method = method;
        this.params = params;
    }
    //
//    @Override
//    public HttpServletRequest getRequest() {
//        return this.request;
//    }
//
//    @Override
//    public HttpServletResponse getResponse() {
//        return this.response;
//    }

    //    public Object execute() {
//        JSONObject fields = WebUtil.fetch(request);
//        Method methodname = ReflectionUtils.findMethod(SpringApplicationContext.getBean(bean).getClass(),
//                method,JSONObject.class,HttpServletResponse.class,HttpServletRequest.class);
//        return ReflectionUtils.invokeMethod(methodname, SpringApplicationContext.getBean(bean), fields,response,request);
//    }
}
