package org.ccpit.base.logManage;

import java.lang.reflect.Method;
import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.ccpit.base.controller.BaseController;
import org.ccpit.base.user.User;
import org.kopitubruk.util.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
 * SystemLogAspect 实现自动编写注解的切点类 <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason:	 TODO ADD REASON. <br/>
 * @author   liyang
 * @version  
 * @since    JDK 1.6
 * @see 	 
 */
@Aspect
@Component
public class SystemLogAspect {
	
	private static final Logger log = LoggerFactory.getLogger(SystemLogAspect.class);
	
	@Autowired
	private LogInfoService infoService;

     //Controller层切点    
    @Pointcut("@annotation(org.ccpit.base.logManage.AutoWriteLog)")
     public  void controllerAspect() {   }    
    
    @Before("controllerAspect()")
    public void invokeBefore(JoinPoint joinPoint){
    	HttpServletRequest request = ((ServletRequestAttributes) 
    			RequestContextHolder.getRequestAttributes()).getRequest();
    	HttpSession session = request.getSession();
    	try{
    	 String ip = request.getRemoteAddr();    
    		User user = (User)session.getAttribute(BaseController.USER_IN_SESSION);
    		log.info("用户名为"+user.getLoginName()+"的用户调用方法"+joinPoint.getTarget().getClass().getName()+
    				"."+joinPoint.getSignature().getName());
    		LogInfo logInfo = new LogInfo();
    		logInfo.setOperateName(joinPoint.getSignature().getName());
    		logInfo.setOperateTime(new Date());
    		logInfo.setOperator(user.getLoginName());
    		logInfo.setOperatorIp(ip);
    		infoService.addLogInfo(logInfo);
    	}catch (Exception e){
    		log.info("记录日志发生异常");
    		log.info("异常信息为"+e.getMessage());
    	}
    }
    @AfterThrowing(pointcut = "controllerAspect()", throwing = "e")
    public void invokeAfter(JoinPoint joinPoint , Throwable e){
    	 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();    
         HttpSession session = request.getSession();    
         //获取请求ip    
         String ip = request.getRemoteAddr();    
         String params = "";    
         if (joinPoint.getArgs() !=  null && joinPoint.getArgs().length > 0) {    
             for ( int i = 0; i < joinPoint.getArgs().length; i++) {    
                params += JSONUtil.toJSON(joinPoint.getArgs()[i]) + ";";    
            }    
        }  
     		//后台用户写日志
    		User user = (User)session.getAttribute("USER_IN_SESSION");
    		log.info("用户名为"+user.getLoginName()+"的用户调用方法"+joinPoint.getTarget().getClass().getName()+
    				"."+joinPoint.getSignature().getName());
    		LogInfo logInfo = new LogInfo();
    		logInfo.setOperateName(joinPoint.getSignature().getName());
    		logInfo.setOperateTime(new Date());
    		logInfo.setOperator(user.getLoginName());
    		logInfo.setOperatorIp(ip);
    		infoService.addLogInfo(logInfo);
     		log.info("异常方法:{"+ joinPoint.getTarget().getClass().getName()+"}"
     				+ "异常代码:{"+ joinPoint.getSignature().getName()+"}"
     						+ "异常信息:{"+ e.getClass().getName(), e.getMessage()+"}"
     								+ "参数:{"+params+"}");    
    } 
    /**  
     * 获取注解中对方法的描述信息 用于Controller层注解  
     *  
     * @param joinPoint 切点  
     * @return 方法描述  
     * @throws Exception  
     */    
     public  static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {    
        String targetName = joinPoint.getTarget().getClass().getName();    
        String methodName = joinPoint.getSignature().getName();    
        Object[] arguments = joinPoint.getArgs();    
        Class targetClass = Class.forName(targetName);    
        Method[] methods = targetClass.getMethods();    
        String description = "";    
         for (Method method : methods) {    
             if (method.getName().equals(methodName)) {    
                Class[] clazzs = method.getParameterTypes();    
                 if (clazzs.length == arguments.length) {    
                    description = method.getAnnotation(AutoWriteLog. class).description();    
                     break;    
                }    
            }    
        }    
         return description;    
    }        
}
