package com.config;

import com.enums.LogEnum;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
import com.jfinal.core.Injector;
import com.jfinal.log.Log;
import com.model.LogDict;
import com.model.User;
import com.tools.JwtUtils;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @ClassName LogInterceptor
 * @Description  日志拦截器
 * @Author zhangyanwei
 * @Date 2020/11/16 16:11
 * @Version 1.0
 **/
public class LogInterceptor implements Interceptor {
    public static Log logger = Log.getLog(LogInterceptor.class);
    private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    com.model.Log log = new com.model.Log().dao();
    LogDict logDict = new LogDict().dao();

    @Override
    public void intercept(Invocation invocation) {
        try {
            HttpServletRequest httpServletRequest = invocation.getController().getRequest();
            System.out.println(httpServletRequest.getRemoteHost());
            String ip = httpServletRequest.getRemoteAddr();
            String url = httpServletRequest.getRequestURI();

            Map<String, String[]> params = httpServletRequest.getParameterMap();
            logger.info("进入日志切面请求url{}"+url);
            List values = new ArrayList();
            values.add(url);
            LogDict record = logDict.findFirst("select   method_name ,oper from t_log_dict where method_path = ?",listToArray(values));
            int type= type(url);
            if(null != record) {

                com.model.Log log1 = new com.model.Log();
                String token = httpServletRequest.getParameter("token");

                User user =getUser(token);
                log1.setIp(ip);
                log1.setReqPath(url);
                String loginname = "";
                if(user != null) {
                    log1.setUserId(user.getId().toString());
                    log1.setCreateName(user.getLoginname());
                    loginname = user.getLoginname();
                }

                String des = getDescription(params,loginname,url, record.getMethodName());
                log1.setReqStatus("200");
                log1.setDescription(des);
                log1.setType(type);
                log1.setLogNo(String.valueOf(UUID.randomUUID()));
                log1.setOper(record.getOper());
                log1.setArgs(argsArrayToString(params));
                log1.save();
            }
            invocation.invoke();
        }catch (Exception e){
            e.printStackTrace();
        }
            return;
        }

    private User getUser(String token) {
        if (null != token) {
            int memberid = JwtUtils.validateJWTForUserId(token);
            User dao = new User().dao();
            User user = dao.findById(memberid);
            if (null != user) {
                return user;
            }

        }
        return null;
    }



    private String getDescription(Map<String,String[]> params,String  userName,String url,  String methodname) {
      StringBuffer   buffer = new StringBuffer();
        Date startTime = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        buffer.append("用户  【"+userName + "】  在").append(sdf.format(startTime) + " <操作了> ");
        if (params.containsKey("clickType")) {
            buffer.append("【" + params.get("clickType")[0] + "】");
            params.remove("clickType");
        }else if(methodname.equals("修改日志配置")){
            buffer.append("【日志配置】修改为"+params.get("file_size")+" G");
        } else {
            buffer.append("【" + methodname + "】");
        }
        for (Map.Entry<String, String[]> entry : params.entrySet()) {
            // 通过参数名去枚举中查找操作
            if (!("").equals(LogEnum.getNameByCode(entry.getKey()))) {
                buffer.append("[").append(LogEnum.getNameByCode(entry.getKey())).append("]:").append(entry.getValue()[0])
                        .append(",");
            }
        }
      return  buffer.toString();
    }


    /**
     * 将List转换为数组对象
     * @param list
     * @return
     */
    public static Object[] listToArray(List<Object> list){
        return list.toArray(new Object[list.size()]);
    }
    public <T> T getBean(Class<T> beanClass, String beanName,HttpServletRequest request) {
        return (T) Injector.injectBean(beanClass, beanName, request, false);
    }

    public int type(String methodPath) {
        int type = 1;
        // 审计日志 日志备份于恢复
        if (methodPath.equals("/log/restoreLog") || methodPath.equals("/log/logBak")||methodPath.equals("/log/list")) {
            type = 2;
        }

        // 日志统计
        if (methodPath.equals("/log/statistics")) {
            type = 2;
        }
        // 日志设置
        if (methodPath.equals("/log/detail") || methodPath.equals("/log/config")) {
            type = 2;
        }

        return type;
    }


    private String argsArrayToString(Map<String,String[]> params) {
        StringBuffer buffer = new StringBuffer();
        params.keySet().forEach(o->{
            buffer.append("{").append(o).append("=").append(params.get(o)[0]).append("}");
        });
        return buffer.toString();
    }
}
