package cn.lihongjie.coal.filter;

import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;

import lombok.SneakyThrows;

import org.apache.commons.io.IOUtils;

import java.io.ByteArrayInputStream;
import java.io.IOException;

public class CacheBodyRequestWrapper extends HttpServletRequestWrapper {

    private final CacheBodyServletInputStream inputStream;

    /**
     * Constructs a request object wrapping the given request.
     *
     * @param request the {@link HttpServletRequest} to be wrapped.
     * @throws IllegalArgumentException if the request is null
     */
    @SneakyThrows
    public CacheBodyRequestWrapper(HttpServletRequest request) {
        super(request);
        inputStream = new CacheBodyServletInputStream(super.getInputStream());

    }

    @Override
    public ServletInputStream getInputStream() throws IOException {

        return inputStream;
    }

    public void reset() {
        inputStream.reset();
    }

    private class CacheBodyServletInputStream extends ServletInputStream {
        private final ServletInputStream stream;
        private final ByteArrayInputStream cache;

        @SneakyThrows
        public CacheBodyServletInputStream(ServletInputStream stream) {
            this.stream = stream;
            cache = new ByteArrayInputStream(IOUtils.toByteArray(stream));
        }

        public void reset() {

            cache.reset();
        }

        @Override
        public boolean isFinished() {
            return cache.available() <= 0;
        }

        @Override
        public boolean isReady() {
            return true;
        }

        @SneakyThrows
        @Override
        public void setReadListener(ReadListener readListener) {

            //            readListener.onAllDataRead();
        }

        @Override
        public int read() throws IOException {
            return cache.read();
        }
    }
}
