package tech.easyflow.log.reporter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.junit.Test;
import org.springframework.web.util.ContentCachingRequestWrapper;
import org.springframework.web.util.ContentCachingResponseWrapper;

import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

/**
 * {@link ResponseCachingFilter} 路径排除行为测试。
 */
public class ResponseCachingFilterTest {

    /**
     * 验证 Agent 媒体下载保持原始响应，避免缓存包装器截断异步文件流。
     *
     * @throws Exception Filter 执行失败
     */
    @Test
    public void agentMediaDownloadShouldBypassResponseCaching() throws Exception {
        HttpServletRequest request = mock(HttpServletRequest.class);
        HttpServletResponse response = mock(HttpServletResponse.class);
        FilterChain chain = mock(FilterChain.class);
        when(request.getMethod()).thenReturn("GET");
        when(request.getRequestURI()).thenReturn("/api/v1/agent/media/document/content");

        ResponseCachingFilter filter = new ResponseCachingFilter(new ActionLogReporterProperties());
        filter.doFilter(request, response, chain);

        verify(chain).doFilter(request, response);
    }

    /**
     * 验证 Artifact 正文下载保持原始响应，避免异步正文被空缓存提前完成。
     *
     * @throws Exception Filter 执行失败
     */
    @Test
    public void agentArtifactContentShouldBypassResponseCaching() throws Exception {
        HttpServletRequest request = mock(HttpServletRequest.class);
        HttpServletResponse response = mock(HttpServletResponse.class);
        FilterChain chain = mock(FilterChain.class);
        when(request.getMethod()).thenReturn("GET");
        when(request.getRequestURI()).thenReturn("/api/v1/agent/artifacts/artifact-1/content");

        ResponseCachingFilter filter = new ResponseCachingFilter(new ActionLogReporterProperties());
        filter.doFilter(request, response, chain);

        verify(chain).doFilter(request, response);
    }

    /**
     * 验证 Artifact 元数据接口仍经过日志正文包装。
     *
     * @throws Exception Filter 执行失败
     */
    @Test
    public void agentArtifactMetadataShouldRemainCacheable() throws Exception {
        HttpServletRequest request = mock(HttpServletRequest.class);
        HttpServletResponse response = mock(HttpServletResponse.class);
        FilterChain chain = mock(FilterChain.class);
        when(request.getMethod()).thenReturn("GET");
        when(request.getRequestURI()).thenReturn("/api/v1/agent/artifacts/artifact-1");

        ResponseCachingFilter filter = new ResponseCachingFilter(new ActionLogReporterProperties());
        filter.doFilter(request, response, chain);

        verify(chain).doFilter(
                isA(ContentCachingRequestWrapper.class), isA(ContentCachingResponseWrapper.class));
    }

    /**
     * 验证近似路径不会误命中 Artifact 正文下载排除规则。
     *
     * @throws Exception Filter 执行失败
     */
    @Test
    public void artifactContentChildPathShouldRemainCacheable() throws Exception {
        HttpServletRequest request = mock(HttpServletRequest.class);
        HttpServletResponse response = mock(HttpServletResponse.class);
        FilterChain chain = mock(FilterChain.class);
        when(request.getMethod()).thenReturn("GET");
        when(request.getRequestURI()).thenReturn("/api/v1/agent/artifacts/artifact-1/content/preview");

        ResponseCachingFilter filter = new ResponseCachingFilter(new ActionLogReporterProperties());
        filter.doFilter(request, response, chain);

        verify(chain).doFilter(
                isA(ContentCachingRequestWrapper.class), isA(ContentCachingResponseWrapper.class));
    }
}
