package zmo.technology.lite.core;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

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

public class ZeroRequestWrapper extends HttpServletRequestWrapper {

	private byte[] rawData;
	private Map<String, String> headers;

	public ZeroRequestWrapper(HttpServletRequest request) throws IOException {
		super(request);
		if (rawData == null) {
			ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int len = 0;
			while ((len = request.getInputStream().read(buffer, 0, 1024)) > 0) {
				swapStream.write(buffer, 0, len);
			}
			rawData = swapStream.toByteArray();
		}
		if (headers == null) {
			Enumeration<String> enumeration = request.getHeaderNames();
			headers = new HashMap<>();
			while (enumeration.hasMoreElements()) {
				String headerName = enumeration.nextElement();
				headers.put(headerName, request.getHeader(headerName));
			}
		}
	}

	class CuracaoServletInputStream extends ServletInputStream {

		private ByteArrayInputStream inputStream = new ByteArrayInputStream(rawData);

		@Override
		public boolean isFinished() {
			return false;
		}

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

		@Override
		public void setReadListener(ReadListener readListener) {
		}

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

		@Override
		public int read(byte[] b) throws IOException {
			return inputStream.read(b);
		}

		@Override
		public int read(byte[] b, int off, int len) throws IOException {

			return inputStream.read(b, off, len);
		}

		@Override
		public void close() throws IOException {
			inputStream.close();
		}
	}

	private CuracaoServletInputStream stream;

	@Override
	public ServletInputStream getInputStream() throws IOException {
		if (stream == null)
			stream = new CuracaoServletInputStream();
		return stream;
	}

	@Override
	public Enumeration<String> getHeaderNames() {
		return Collections.enumeration(headers.keySet());
	}
}