package com.ssm.common;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Date;
import java.util.Map;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

import com.ssm.model.system.SysLog;
import com.ssm.model.system.SysUser;
import com.ssm.service.system.SysLogService;
import com.ssm.util.Util;

/**
 * 增强的controller 统一处理异常
 * 
 * @author
 */
@ControllerAdvice
public class ExceptionReaper {
	
	@Autowired
	SysLogService sysLogService;
	
	/**
	 * 处理 500 异常 
	 * 暂时未记录到数据库
	 * @param e
	 * @param request
	 * @return
	 */
	@ExceptionHandler({ Error.class, Exception.class, Throwable.class })
	public String exception(Exception e, HttpServletRequest request,HttpSession session) {
		e.printStackTrace();
		request.setAttribute("exceptionMessage", e.getMessage());
		if(e instanceof SessionTimeOutException){
			// session_time_out不记录日志
			return "sessionOut";

		}
		if(e instanceof UndeclaredThrowableException){
			if( ((UndeclaredThrowableException) e).getUndeclaredThrowable() instanceof PermissionDeniedException ) {
				PermissionDeniedException e1 = (PermissionDeniedException) ((UndeclaredThrowableException) e).getUndeclaredThrowable();
				saveLog(e1, request, session);
				return "permissionDenied";
			} else {
				saveLog(e, request, session);
				return "error";
			}	
		} else {
			saveLog(e, request, session);
			return "error";
		}
	}
	
	public void saveLog(Exception e, HttpServletRequest request,HttpSession session){
		String uri = request.getRequestURI();
		String ex = e.getMessage();
		StringWriter str = new StringWriter();
		e.printStackTrace(new PrintWriter(str));
		String e1 = str.getBuffer().toString();
		SysUser sysUser = Util.getUserSession(request);
		
		String clazzName = uri.split("/")[uri.split("/").length-2];
		String methodName = uri.split("/")[uri.split("/").length-1];
		
		StringBuilder sb = new StringBuilder();
		Map<String, String[]> paramMap = request.getParameterMap();
		for (String key : paramMap.keySet()) {
			String[] values = paramMap.get(key);
			if(values.length == 1) {
				sb.append("{ param = "+ key + " and value = " + values[0].toString());
				sb.append(" }");
			} else {
				sb.append("{ param = "+ key + " and value = " );
				for(String value : values){
					sb.append(value +" , ");
				}
				sb.append(" }");
			}
			System.out.println(sb.toString());
		}
		String remoteIP = request.getRemoteAddr();
		SysLog sysLog = new SysLog();
		sysLog.setLogLevel("error");
		sysLog.setStackTrace(e1);
		sysLog.setOrigin(clazzName+"."+methodName);
		sysLog.setUserId(sysUser != null ?sysUser.getUserid(): -1);
		sysLog.setCreatedDate(new Date());
		sysLog.setLogMessage(ex);
		sysLog.setParams(sb.toString());
		sysLog.setIpAddress(remoteIP);
		sysLogService.insert(sysLog);
	}
	
}
