package com.nokia.hb.config.web;

import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.lang.Nullable;
import org.springframework.util.StopWatch;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.Charset;
import java.util.UUID;

/**
 * 请求日志拦截器
 */
@Slf4j
public class RequestLogHandlerInterceptor implements HandlerInterceptor {
    /**
     * 计时器线程变量
     */
    private static final ThreadLocal<StopWatch> STOP_WATCH_THREAD_LOCAL = new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 计时器放入线程变量
        STOP_WATCH_THREAD_LOCAL.set(stopWatch);
        // 日志添加跟踪id
        MDC.put("traceId", UUID.randomUUID().toString().replace("-", ""));
        log.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
//        // 请求头参数
//        Map<String, String> headers = new HashMap<>();
//        Enumeration<String> headerNames = request.getHeaderNames();
//        while (headerNames.hasMoreElements()) {
//            String k	= headerNames.nextElement();
//            String v = request.getHeader(k);
//            headers.put(k, v);
//        }
//        log.info("请求头参数: {}", JSON.toJSONString(headers));
//        // 查询参数
//        Map<String, String> parameters = new HashMap<>();
//        Enumeration<String> parameterNames = request.getParameterNames();
//        while (parameterNames.hasMoreElements()) {
//            String k	= parameterNames.nextElement();
//            String v = request.getParameter(k);
//            parameters.put(k, v);
//        }
//        log.info("查询参数: {}", JSON.toJSONString(parameters));
        // 请求体参数
        String body = StreamUtils.copyToString(request.getInputStream(), Charset.forName(request.getCharacterEncoding()));
        log.info("请求参数: {}", StringUtils.trimAllWhitespace(body));
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                @Nullable Exception ex) throws Exception {
        if (!request.getRequestURI().equals("/api/renderTable")) {
            MyHttpServletResponseWrapper wrapper = (MyHttpServletResponseWrapper) response;
            String responseString = new String(wrapper.toByteArray(), Charset.forName(request.getCharacterEncoding()));
            log.info("返回 {}: {}", wrapper.getStatus(), responseString);
        } else {
            log.info("返回 {}", response.getStatus());
        }
        StopWatch stopWatch = STOP_WATCH_THREAD_LOCAL.get();
        stopWatch.stop();
        log.info("耗时 {} ms", stopWatch.getTotalTimeMillis());
        STOP_WATCH_THREAD_LOCAL.remove();
    }
}