package com.ylcm.sys.interceptor;

import java.util.Enumeration;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.ylcm.sys.common.Constants;
import com.ylcm.sys.common.EnumHelperUtil;
import com.ylcm.sys.common.RequestUtil;
import com.ylcm.sys.domain.User;
import com.ylcm.sys.enums.UrlEnum;
import com.ylcm.sys.service.LogService;

import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class LogInfoInterceptor implements HandlerInterceptor {
	private static final String API_STARTTIME_KEY = "api_starttime";
    private static final String LOG_TITLE = "request log:";
    
    @Resource
    private LogService logService;

	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        // TODO Auto-generated method stub
    }

	/**
	 * 请求执行完成后
	 */
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView arg3)
            throws Exception {
    	long end = System.currentTimeMillis();
    	long start = (long) request.getAttribute(API_STARTTIME_KEY);
		long time = end - start;
		String ip = RequestUtil.getIpAddr(request);
		String params = getRequestParams(request);
		String uri = request.getRequestURI();
		String url = request.getRequestURL().toString().replace(Constants.PATH_BASE, "");
    	if (time > 500) {
			log.warn("{}{} 执行结束,用时：{}, 请求参数：{}", LOG_TITLE, uri, time, params);
		}else{
			log.info("{}{} 执行结束,用时：{}", LOG_TITLE, uri, time);
		}
    	
    	if (url.contains("logout")) {
			return;
		}
    	
    	User user = (User) request.getSession().getAttribute("manager");
    	if (user != null) {
    		String[] codes = url.split("/");
    		if (codes.length == 2 && "index.do".equals(codes[1])) {
            	UrlEnum urlEnum = EnumHelperUtil.getOneByCode(UrlEnum.class, codes[0]);
            	if (urlEnum == null) {
					if ("ad-special".equals(codes[0]) && "0".equals(request.getParameter("type"))) {
						logService.saveLog(Constants.LOG_TYPE_VIEW, user.getLoginName(), user.getNickName(), ip, "访问了" + UrlEnum.SPECIAL_AD.getName());
					} else if ("ad-special".equals(codes[0]) && "1".equals(request.getParameter("type"))) {
						logService.saveLog(Constants.LOG_TYPE_VIEW, user.getLoginName(), user.getNickName(), ip, "访问了" + UrlEnum.SPECIAL_PL.getName());
					}
				} else {
	             	logService.saveLog(Constants.LOG_TYPE_VIEW, user.getLoginName(), user.getNickName(), ip, "访问了" + (urlEnum != null ? urlEnum.getName() : ""));
				}
			} else if(codes.length == 1) {
	        	UrlEnum urlEnum = EnumHelperUtil.getOneByCode(UrlEnum.class, codes[0].replace(".do", ""));
	        	if (urlEnum != null) {
		         	logService.saveLog(Constants.LOG_TYPE_VIEW, user.getLoginName(), user.getNickName(), ip, "访问了" + (urlEnum != null ? urlEnum.getName() : ""));
				}
			}
		}
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object arg2) throws Exception {
    	request.setAttribute(API_STARTTIME_KEY, System.currentTimeMillis());
    	
    	logRequestParams(request);
    	
        return true;
    }
    
    /**
	 * 添加请求及参数日志
	 */
	private void logRequestParams(HttpServletRequest request){
		log.info(new StringBuffer(LOG_TITLE).append(getRequestParams(request)).toString());
	}
	
	private String getRequestParams(HttpServletRequest request){
		StringBuffer buf = new StringBuffer();
		
		buf.append(request.getRequestURI());
		Enumeration<String> params = request.getParameterNames();
		int i = 0;
		while (params.hasMoreElements()) {
			String name = (String) params.nextElement();
			buf.append(i++ > 0 ? "&":"?").append(name).append("=").append(request.getParameter(name));
		}
		
		/*
         * 取body中的数据并打印
         */
        String contentType = request.getContentType();
        if (contentType != null && contentType.contains("application/json")) {
            String requestBody = RequestUtil.getRequestPayload(request);
            if (StringUtils.isNotBlank(requestBody)) {
                buf.append(i > 0 ? "&":"?").append("bodyParams=").append(requestBody);
            }
        }
		
		return buf.toString();
	}
}
