package com.liquidnet.common.web.aop;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @author <a href="mailto:guo_xp@163.com">guoxinpeng</a>
 * @version 1.0 2016/11/23 18:48
 * @projectname new-pay
 * @packname com.liquidnet.service.config.aop
 */
@Aspect
@Component
public class CtrlAop {
  protected Logger logger = LoggerFactory.getLogger(CtrlAop.class);

  @Around("execution(* com.liquidnet.service.*..*RestController.*(..))")
  public Object ctrlLog(ProceedingJoinPoint proceed) throws Throwable {
    Object[] objs = proceed.getArgs();
    JSONObject params = new JSONObject();
    String disUrl = proceed.getSignature().getDeclaringTypeName() + "." + proceed.getSignature().getName();
    logger.info("CTRL目标方法:\t{}", disUrl);

      RequestAttributes ra = RequestContextHolder.getRequestAttributes();
      ServletRequestAttributes sra = (ServletRequestAttributes) ra;
      HttpServletRequest request = sra.getRequest();


//      for (int i = 0; i < objs.length; i++) {
//      Object obj = objs[i];
//      if (null != obj)
//        params.put(obj.getClass().getName()+"["+i+"]", obj);
//    }

    logger.info("CTRL目标方法:\t{} \n  CTRL参数:\t{}", disUrl,JSON.toJSONString(request.getParameterMap()));
    Object result = proceed.proceed();
    logger.info("CTRL目标方法:\t{} \n  CTRL返回结果:\t{}", disUrl , null == result ? "null" : JSONObject.toJSON(result).toString());
    return result;
  }

  public static boolean isWrapClass(Class clz) {
    String[] types = {"java.lang.Integer", "java.lang.Double", "java.lang.Float", "java.lang.Long", "java.lang.Short", "java.lang.Byte", "java.lang.Boolean", "java.lang.Character", "java.lang.String", "int", "double", "long", "short", "byte", "boolean", "char", "float"};
    List<String> tempList = Arrays.asList(types);
    if (tempList.contains(clz.getName())) {
        return true;
    } else {
        return false;
    }
  }

  public static JSONObject str(Object obj) throws IntrospectionException, InvocationTargetException, IllegalAccessException {
    JSONObject param = new JSONObject();
    Class clazz = obj.getClass();
    if (isWrapClass(clazz)) {
      param.put(clazz.getName(), obj);
    } else {
      Field[] fields = clazz.getDeclaredFields();
      for (int j = 0; j < fields.length; j++) {
        Field field = fields[j];

        PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
        Method getMethod = pd.getReadMethod();//获得get方法
        Object o = getMethod.invoke(obj);//执行get方法返回一个Object
        if (isWrapClass(field.getType())) {
          param.put(field.getName(), o);
        } else {
          if (null != o) {
            param.put(field.getName(), str(o));
          } else {
            param.put(field.getName(), null);
          }
        }
      }
    }
    return param;
  }
}
