package com.yonge.log.interceptor;

import java.io.IOException;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.ym.mec.util.json.JsonUtil;
import com.ym.mec.util.web.WebUtil;
import com.yonge.log.dal.model.AuditLog;
import com.yonge.log.model.AuditLogAnnotation;
import com.yonge.log.service.AuditLogService;

/**
 * 日志审计的拦截器
 */
public class AuditLogInterceptor extends HandlerInterceptorAdapter {

	@Autowired
	private AuditLogService auditLogService;

	@Value("${spring.application.name}")
	private String clientName;

	private String username;

	private Integer userId;

	private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	private static List<String> ignoreLogUrl;



	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {

		return true;
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
		try {
			String servletPath = request.getServletPath();
			HandlerMethod handlerMethod = (HandlerMethod) handler;
			AuditLogAnnotation anno = handlerMethod.getMethodAnnotation(AuditLogAnnotation.class);
			ApiOperation apiOperation = handlerMethod.getMethodAnnotation(ApiOperation.class);
			String operateName = null;
			if(StringUtils.isEmpty(operateName) && apiOperation != null){
				operateName = apiOperation.value();
			}
			if(StringUtils.isEmpty(operateName) && anno != null){
				operateName = anno.operateName();
			}
			if(anno != null){
				saveLog(operateName,servletPath,request);
				return;
			}
			if(servletPath.contains("/task/") || servletPath.contains("/import/") ){
				return;
			}
			String substring = servletPath.substring(servletPath.lastIndexOf("/") + 1).toLowerCase();
			if(ignoreLogUrl == null){
				ignoreLogUrl = new ArrayList<>();
				ignoreLogUrl.add("query");
				ignoreLogUrl.add("get");
				ignoreLogUrl.add("find");
				ignoreLogUrl.add("list");
				ignoreLogUrl.add("detail");
				ignoreLogUrl.add("hasindexerrdata");
				ignoreLogUrl.add("newindex");
			}
			for (String e : ignoreLogUrl) {
				if(substring.contains(e)){
					return;
				}
			}
			saveLog(operateName,servletPath,request);
		}catch (Exception e){
			e.printStackTrace();
		}
	}

	private void saveLog(String operateName,String servletPath,HttpServletRequest request) throws IOException {
		AuditLog auditLog = new AuditLog();
		auditLog.setOperateName(operateName);
		auditLog.setInterfaceUrl(servletPath);
		auditLog.setToken(request.getHeader("Authorization"));
		auditLog.setService(clientName);
		auditLog.setUserIp(WebUtil.getRemoteIp(request));

		Map<String, Object> params = WebUtil.getParameterMap(request);
		if (params == null || params.size() == 0) {
			auditLog.setInputParams(IOUtils.toString(request.getInputStream(), Charset.defaultCharset()));
		} else {
			auditLog.setInputParams(JsonUtil.toJSONString(WebUtil.getParameterMap(request)));
		}
		// 操作人
		auditLog.setUsername(username);
		auditLog.setUserId(userId);
		auditLog.setOperateTime(sdf.format(new Date()));
		auditLogService.insert(auditLog);
	}

	public void setUsername(String username,Integer userId) {
		this.username = username;
		this.userId = userId;
	}
}
