package com.wms_main.filter;

import com.wms_main.model.pojo.log.RequestLog;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import java.io.IOException;

@Slf4j
@Component
@WebFilter(filterName = "requestLogFilter", urlPatterns = "/*")
public class RequestLogFilter extends HttpFilter {
    @Override
    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        // Wrapper封装request和response
        ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
        ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
        // 继续执行请求链
        chain.doFilter(requestWrapper, responseWrapper);
        // 请求方法
        String method = request.getMethod();
        // URI
        String uri = request.getRequestURI();
        // 客户端主机名
        String remoteHost = request.getRemoteHost();
        // 客户端ip地址
        String remoteAddr = request.getRemoteAddr();
        // 请求体
        byte[] requestContent = requestWrapper.getContentAsByteArray();
        // 响应状态
        int status = response.getStatus();
        // 响应体
        byte[] responseContent = responseWrapper.getContentAsByteArray();
        // 记录日志信息
        String requestContentString = formatContentString(new String(requestContent));
        String responseContentString = formatContentString(new String(responseContent));
        RequestLog logInfo = new RequestLog(method, uri, remoteHost, remoteAddr, requestContentString, String.valueOf(status), responseContentString);
        log.info(logInfo.toString());
        // TODO 增加存储数据库的操作

        // 把缓存的响应数据，响应给客户端
        responseWrapper.copyBodyToResponse();
    }

    /**
     * 格式化内容string
     * @param contentString 原始字符串
     * @return 格式化之后的字符串
     */
    private String formatContentString (String contentString) {
        String newContentString = contentString.replaceAll("\\s*", "");
        if (newContentString.length() > 1024) {
            newContentString = newContentString.substring(0, 1024) + "...";
        }
        return newContentString;
    }
}
