import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.glodon.bim5d.controller.BaseController;
import com.glodon.bim5d.util.LoggerMsgUtil;


@Aspect
@Component
public class LogAspect {
	
    @Pointcut("execution(public void xxx.xxx.xxx.controller.QRCodeController.download(..))")  
    public void pointCut() {  
    }  
  
    @Before("pointCut()")  
    public void before(JoinPoint joinPoint) throws Exception {
            //获得代理类  
    	BaseController controller = (BaseController)joinPoint.getTarget();
    	//获得request
    	HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
    	String uri = request.getRequestURI();
    	String queryString = request.getQueryString();
    	String projectId = getProjectId(joinPoint);
		try {
			HashMap inputParam = new HashMap();
			inputParam.put("uri", uri);
			inputParam.put("projectId", projectId);
			inputParam.put("RequestBody", queryString);
			LoggerMsgUtil.enterMethodInfo(controller.getLogger(), inputParam);
		} catch (Exception e) {
			LoggerMsgUtil.Info(controller.getLogger(), "记录入口参数失败:{0}", e.getMessage());
		}	
    }  
    
    /**
     * 从参数列表中获取projectId
     * 
     */
    private String getProjectId(JoinPoint joinPoint){
    	String projectId = null;
    	try {
            //获取参数名称和值  
            Map nameAndArgs = getFieldsNameValueMap(joinPoint);  
            projectId = nameAndArgs.get("projectId") == null ? null : String.valueOf(nameAndArgs.get("projectId"));
		} catch (Exception e) {
		}
        return projectId;
    }
    
    private Map getFieldsNameValueMap(JoinPoint joinPoint) throws Exception {   
    	Object[] args = joinPoint.getArgs();
    	String classType = joinPoint.getTarget().getClass().getName();    
        Class clazz = Class.forName(classType);    
        String clazzName = clazz.getName();    
        String methodName = joinPoint.getSignature().getName(); //获取方法名称   
        Map map=new HashMap();  
        ClassPool pool = ClassPool.getDefault();    
        ClassClassPath classPath = new ClassClassPath(this.getClass());    
        pool.insertClassPath(classPath);    
        CtClass cc = pool.get(clazzName);    
        CtMethod cm = cc.getDeclaredMethod(methodName);    
        MethodInfo methodInfo = cm.getMethodInfo();  
        CodeAttribute codeAttribute = methodInfo.getCodeAttribute();    
        LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);    
        if (attr == null) {    
            throw new RuntimeException();
        }    
        int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;    
        for (int i = 0; i < cm.getParameterTypes().length; i++){    
            map.put( attr.variableName(i + pos),args[i]);//paramNames即参数名    
        }    
        return map;    
    }    
}