package xtools.boot.web.base.filter;

import jakarta.annotation.Resource;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.jspecify.annotations.NonNull;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import xtools.base.config.BaseParams;
import xtools.boot.api.constant.BootCommonConstant;
import xtools.boot.api.model.dto.log.HolderLogTrack;
import xtools.boot.core.utils.PathPatternUtils;
import xtools.boot.log.holder.LogTrackHolder;
import xtools.boot.web.base.config.LogTrackConfig;
import xtools.boot.web.filter.base.BaseFilter;
import xtools.core.StringUtils;
import xtools.web.HeaderUtils;

import java.io.IOException;

/**
 * <p>Title : LogTrackFilter</p>
 * <p>Description : LogTrackFilter</p>
 * <p>DevelopTools : Idea_x64_v2026.1</p>
 * <p>DevelopSystem : macOS Sequoia 15.7.5</p>
 * <p>Company : org.xujun</p>
 *
 * @author : XuJun
 * @version : 5.0.0
 * @date : 2026/1/6 16:37
 */
@Slf4j
@Component
public class LogTrackFilter extends BaseFilter implements Ordered, BaseParams {

    @Resource
    private LogTrackConfig logTrackConfig;

    @Override
    public int getOrder() {
        return CP_NUM100;
    }

    @Override
    protected void doFilterInternal(
            @NonNull HttpServletRequest request,
            @NonNull HttpServletResponse response,
            @NonNull FilterChain filterChain
    ) {
        String uri = HeaderUtils.getUri(request);
        String headerLogTrack = HeaderUtils.getHeader(request, BootCommonConstant.LOG_TRACK);
        HolderLogTrack logTrack;
        if (StringUtils.isBlank(headerLogTrack)) {
            logTrack = LogTrackHolder.newMain();
        } else {
            logTrack = LogTrackHolder.newByBase64(headerLogTrack);
        }
        ScopedValue.where(LogTrackHolder.getScoped(), logTrack).run(() -> {
            // 判断该uri是否忽略记录日志
            if (PathPatternUtils.match(logTrackConfig.getIgnorePath(), uri)) {
                LogTrackHolder.saveLog(false);
            }
            try {
                filterChain.doFilter(request, response);
            } catch (IOException | ServletException e) {
                printLog(e, "添加日志追踪ScopedValue异常");
            }
        });
    }

}
