package com.yihu.hos.interceptor;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yihu.hos.common.HosAdminLogger;
import com.yihu.hos.common.constants.ContextAttributes;
import com.yihu.hos.system.model.SystemUser;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
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;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;

/**
 * 记录数据交换平台业务请求的日志
 *
 * @author 张进军
 * @date 2017.7.6 16::06
 */
@Aspect
@Component
public class HosAdminLogAspect {
    private static Logger logger = LoggerFactory.getLogger(HosAdminLogAspect.class);

    private String requestPath; // 请求地址
    private String operationPath; //操作地址（去掉项目部署名称的地址）
    private String userName; // 用户名
    private String function; // 操作页面名称
    private String operation; // 操作内容（增、删、改、查、导入）
    private Map<?, ?> inputParamMap = null; // 传入参数
    private Map<String, Object> outputParamMap = null; // 输出结果
    private long startTimeMillis = 0; // 开始时间
    private long endTimeMillis = 0; // 结束时间

    @Autowired
    private ObjectMapper objectMapper;

    @Before("execution(* com.yihu.hos.*.controller..*.*(..))")
    public void doBeforeInServiceLayer(JoinPoint joinPoint) {
        startTimeMillis = System.currentTimeMillis();
    }

    @After("execution(* com.yihu.hos.*.controller..*.*(..))")
    public void doAfterInServiceLayer(JoinPoint joinPoint) throws JsonProcessingException {
        endTimeMillis = System.currentTimeMillis();
        // 记录请求日志
        this.recordLog();
    }

    @Around("execution(* com.yihu.hos.*.controller..*.*(..))")
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        operationPath = request.getServletPath();
        inputParamMap = request.getParameterMap();
        requestPath = request.getRequestURL().toString();
        Object result = pjp.proceed();
        outputParamMap = new HashMap<String, Object>();
        outputParamMap.put("result", result);
        return result;
    }

    /**
     * 记录请求日志
     */
    private void recordLog() throws JsonProcessingException {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        HttpSession session = request.getSession();

        SystemUser systemUser = (SystemUser) session.getAttribute(ContextAttributes.USER_INFO);
        String loginCode = systemUser == null ? "" : systemUser.getLoginCode();
        String userName = systemUser == null ? "" : systemUser.getUserName();

        ObjectNode data = objectMapper.createObjectNode();
        data.put("patient", userName); // 调用者
        data.put("url", requestPath); // 调用的控制器路径
        data.put("responseTime", endTimeMillis - startTimeMillis); // 响应时长
        data.put("responseCode", response.getStatus()); // 响应状态
        data.put("response", objectMapper.writeValueAsString(outputParamMap)); // 请求返回的结果
        data.put("appKey", "ESB"); // 应用名称：共享交换平台
        data.put("param", objectMapper.writeValueAsString(inputParamMap)); // 请求传递的参数

        HosAdminLogger.info(loginCode, data);
    }

}
