package com.atlassian.bitbucket.mesh.test.util.http;

import com.sun.net.httpserver.HttpExchange;

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Vector;

class HttpServletRequestAdapter extends FakeHttpServletRequest {

    private final HttpExchange exchange;

    public HttpServletRequestAdapter(HttpExchange exchange) {
        this.exchange = exchange;
    }

    @Override
    public String getContentType() {
        return exchange.getRequestHeaders().getFirst("Content-Type");
    }

    @Override
    public String getHeader(String name) {
        return exchange.getRequestHeaders().getFirst(name);
    }

    @Override
    public long getContentLengthLong() {
        String contentLength = getHeader("Content-Length");
        if (contentLength == null) {
            return -1;
        }
        return Long.parseLong(contentLength);
    }

    @Override
    public Enumeration<String> getHeaderNames() {
        return new Vector<>(exchange.getRequestHeaders().keySet()).elements();
    }

    @Override
    public Enumeration<String> getHeaders(String name) {
        return new Vector<>(exchange.getResponseHeaders().get(name)).elements();
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {
        InputStream request = exchange.getRequestBody();
        return new ServletInputStream() {

            boolean finished = false;

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

            @Override
            public boolean isReady() {
                return !finished;
            }

            @Override
            public int read() throws IOException {
                int read = request.read();
                if (read == -1) {
                    finished = true;
                }
                return read;
            }

            @Override
            public int read(byte[] b, int off, int len) throws IOException {
                int read = request.read(b, off, len);
                if (read == -1) {
                    finished = true;
                }
                return read;
            }

            @Override
            public void setReadListener(ReadListener readListener) {
                throw new UnsupportedOperationException();
            }
        };
    }

    @Override
    public String getMethod() {
        return exchange.getRequestMethod();
    }

    @Override
    public String getProtocol() {
        return exchange.getProtocol();
    }

    @Override
    public String getQueryString() {
        return exchange.getRequestURI().getQuery();
    }

    @Override
    public String getRemoteAddr() {
        return exchange.getRemoteAddress().getAddress().getHostAddress();
    }

    @Override
    public String getRemoteHost() {
        return getRemoteAddr();
    }

    @Override
    public int getRemotePort() {
        return exchange.getRemoteAddress().getPort();
    }

    @Override
    public String getServerName() {
        return exchange.getLocalAddress().getAddress().toString();
    }

    @Override
    public int getServerPort() {
        return exchange.getLocalAddress().getPort();
    }
}
