package tech.easyflow.ai.utils;

import com.sun.net.httpserver.HttpServer;
import org.junit.Assert;
import org.junit.Test;

import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.util.Arrays;

/**
 * DocUtil 流式下载测试。
 */
public class DocUtilStreamingDownloadTest {

    /**
     * 验证大响应按流落盘、内容完整且关闭后清理临时文件。
     *
     * @throws Exception 测试服务器或文件读取失败时抛出
     */
    @Test
    public void shouldStreamResponseToTemporaryFileAndCleanup() throws Exception {
        byte[] content = new byte[2 * 1024 * 1024 + 17];
        Arrays.fill(content, (byte) 7);
        HttpServer server = startServer(content);
        try {
            String url = "http://127.0.0.1:" + server.getAddress().getPort() + "/download";
            java.nio.file.Path path;
            try (DocUtil.DownloadedFile downloadedFile =
                         DocUtil.downloadFileToTemp(url, content.length + 1L)) {
                path = downloadedFile.path();
                Assert.assertEquals(content.length, downloadedFile.size());
                Assert.assertEquals("application/octet-stream", downloadedFile.contentType());
                Assert.assertArrayEquals(content, Files.readAllBytes(path));
            }
            Assert.assertFalse(Files.exists(path));
        } finally {
            server.stop(0);
        }
    }

    /**
     * 验证超过配置上限时显式失败。
     *
     * @throws Exception 测试服务器初始化失败时抛出
     */
    @Test
    public void shouldRejectResponseAboveConfiguredLimit() throws Exception {
        byte[] content = new byte[1024];
        HttpServer server = startServer(content);
        try {
            String url = "http://127.0.0.1:" + server.getAddress().getPort() + "/download";
            try {
                DocUtil.downloadFileToTemp(url, content.length - 1L);
                Assert.fail("expected download limit failure");
            } catch (RuntimeException exception) {
                Assert.assertTrue(exception.getCause().getMessage().contains("超过限制"));
            }
        } finally {
            server.stop(0);
        }
    }

    /**
     * 启动仅用于本测试的本地 HTTP 文件服务。
     *
     * @param content 响应内容
     * @return 已启动的 HTTP 服务
     * @throws Exception 服务创建失败时抛出
     */
    private HttpServer startServer(byte[] content) throws Exception {
        HttpServer server = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0);
        server.createContext("/download", exchange -> {
            exchange.getResponseHeaders().set("Content-Type", "application/octet-stream");
            exchange.sendResponseHeaders(200, content.length);
            try (OutputStream output = exchange.getResponseBody()) {
                for (int offset = 0; offset < content.length; offset += 8192) {
                    int length = Math.min(8192, content.length - offset);
                    output.write(content, offset, length);
                }
            }
        });
        server.start();
        return server;
    }
}
