package cn.skcks.docking.gb28181.wvp.service.download;

import cn.hutool.core.io.IoUtil;
import cn.skcks.docking.gb28181.common.json.JsonResponse;
import jakarta.servlet.AsyncContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.hc.client5.http.classic.methods.HttpGet;
import org.apache.hc.client5.http.classic.methods.HttpHead;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Optional;

@Slf4j
@Service
public class DownloadService {
    @SneakyThrows
    public void header(HttpServletRequest request, HttpServletResponse response, String url) {
        AsyncContext asyncContext = request.startAsync();
        asyncContext.setTimeout(0);
        asyncContext.start(() -> {
            try {
                response.setHeader("Accept-Ranges", "none");
                response.setHeader("Connection", "close");
                header((HttpServletResponse) asyncContext.getResponse(), url);
            } finally {
                log.info("record 结束");
                asyncContext.complete();
            }
        });
    }

    @SneakyThrows
    private void header(HttpServletResponse response, String url) {
        try (CloseableHttpClient client = HttpClients.custom().build()) {
            HttpHead httpHead = new HttpHead(url);
            client.execute(httpHead, resp -> {
                setHeaderFromProxy(resp,response);
                return null;
            });
        }
    }

    @SneakyThrows
    private void setHeaderFromProxy(ClassicHttpResponse resp, HttpServletResponse response){
        response.setContentType(resp.getEntity().getContentType());
        Optional.ofNullable(resp.getHeader("Content-Disposition")).ifPresent((header)->{
            response.setHeader(header.getName(), header.getValue());
        });
    }

    @SneakyThrows
    public void download(AsyncContext asyncContext , HttpServletResponse response, String url) {
        asyncContext.start(() -> {
            try {
                response.setHeader("Accept-Ranges", "none");
                response.setHeader("Connection", "close");
                download((HttpServletResponse) asyncContext.getResponse(), url);
            } finally {
                log.info("record 结束");
                asyncContext.complete();
            }
        });
    }

    @SneakyThrows
    public void download(HttpServletRequest request, HttpServletResponse response, String url) {
        AsyncContext asyncContext = request.startAsync();
        asyncContext.setTimeout(0);
        download(asyncContext, response, url);
    }

    @SneakyThrows
    public void download(HttpServletResponse response, String url) {
        OutputStream outputStream = response.getOutputStream();

        try (CloseableHttpClient client = HttpClients.custom().build()) {
            HttpGet httpGet = new HttpGet(url);
            client.execute(httpGet, resp -> {
                setHeaderFromProxy(resp,response);
                InputStream stream = resp.getEntity().getContent();
                IoUtil.copy(stream, outputStream);
                return stream;
            });
        }
    }
}
