package com.github.to2mbn.jyal.io;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Map.Entry;

public class HttpRequester {

	private static final int TIMEOUT = 15000;
	private static final int BUFFER_SIZE = 8192;

	private Proxy proxy;

	public HttpRequester() {
		this(null);
	}

	public HttpRequester(Proxy proxy) {
		this.proxy = proxy == null ? Proxy.NO_PROXY : proxy;
	}

	public Proxy getProxy() {
		return proxy;
	}

	public String get(String url, Map<String, Object> arguments) throws UnsupportedEncodingException, MalformedURLException, IOException {
		HttpURLConnection connection = createHttpConnection(url, arguments);
		connection.setRequestMethod("GET");
		try {
			connection.connect();
			try (InputStream in = connection.getInputStream()) {
				return read(in);
			}
		} catch (IOException e) {
			try (InputStream in = connection.getErrorStream()) {
				if (in == null) {
					throw e;
				}
				return read(in);
			} catch (IOException e1) {
				e1.addSuppressed(e);
				throw e;
			}
		} finally {
			connection.disconnect();
		}
	}

	public String post(String url, Map<String, Object> arguments, String post, String contentType) throws UnsupportedEncodingException, MalformedURLException, IOException {
		byte[] rawpost = post.getBytes("UTF-8");

		HttpURLConnection connection = createHttpConnection(url, arguments);
		connection.setRequestMethod("POST");
		connection.setRequestProperty("Content-Type", contentType + "; charset=utf-8");
		connection.setRequestProperty("Content-Length", String.valueOf(rawpost.length));
		connection.setDoOutput(true);

		try {
			connection.connect();
			try (OutputStream out = connection.getOutputStream()) {
				out.write(rawpost);
			}
			try (InputStream in = connection.getInputStream()) {
				return read(in);
			}
		} catch (IOException e) {
			try (InputStream in = connection.getErrorStream()) {
				if (in == null) {
					throw e;
				}
				return read(in);
			} catch (IOException e1) {
				e1.addSuppressed(e);
				throw e;
			}
		} finally {
			connection.disconnect();
		}
	}

	private String read(InputStream in) throws UnsupportedEncodingException, IOException {
		StringBuilder sb = new StringBuilder();
		char[] buffer = new char[BUFFER_SIZE];
		Reader reader = new InputStreamReader(in, "UTF-8");
		int read;
		while ((read = reader.read(buffer)) != -1) {
			sb.append(buffer, 0, read);
		}
		return sb.toString();
	}

	private HttpURLConnection createHttpConnection(String baseurl, Map<String, Object> arguments) throws UnsupportedEncodingException, MalformedURLException, IOException {
		String url = baseurl;
		if (arguments != null) {
			url = url + "?" + generateArguments(arguments);
		}
		return createHttpConnection(new URL(url));
	}

	private HttpURLConnection createHttpConnection(URL url) throws IOException {
		HttpURLConnection connection = (HttpURLConnection) url.openConnection(proxy);
		connection.setConnectTimeout(TIMEOUT);
		connection.setReadTimeout(TIMEOUT);
		connection.setUseCaches(false);
		return connection;
	}

	private String generateArguments(Map<String, Object> arguments) throws UnsupportedEncodingException {
		StringBuilder result = new StringBuilder();
		for (Entry<String, Object> argument : arguments.entrySet()) {
			result.append(URLEncoder.encode(argument.getKey(), "UTF-8"));
			result.append('=');
			result.append(URLEncoder.encode(String.valueOf(argument.getValue()), "UTF-8"));
			result.append('&');
		}
		result.deleteCharAt(result.length() - 1);
		return result.toString();
	}

}

@@ -1195,133 +1195,37 @@
 %09%09%09%09
-if (in == null) %7B%0A%09%09%09%09%09throw e;%0A%09%09%09%09%7D%0A%09%09%09%09return read(in);%0A%09%09%09%7D catch (IOException e1) %7B%0A%09%09%09%09e1.addSuppressed(e);%0A%09%09%09%09throw
+return readErrorStream(in,
  e
+)
 ;%0A%09%09
@@ -2088,16 +2088,188 @@
 ()) %7B%0A%09%09
+%09%09return readErrorStream(in, e);%0A%09%09%09%7D%0A%09%09%7D finally %7B%0A%09%09%09connection.disconnect();%0A%09%09%7D%0A%09%7D%0A%0A%09private String readErrorStream(InputStream in, IOException e) throws IOException %7B%0A
 %09%09if (in
@@ -2283,18 +2283,16 @@
 l) %7B%0A%09%09%09
-%09%09
 throw e;
@@ -2294,21 +2294,26 @@
 ow e;%0A%09%09
-%09
-%09
 %7D%0A%09
+%09try %7B%0A
 %09%09%09retur
@@ -2326,17 +2326,16 @@
 (in);%0A%09%09
-%09
 %7D catch 
@@ -2349,24 +2349,42 @@
 ption e1) %7B%0A
+%09%09%09if (e != e1) %7B%0A
 %09%09%09%09e1.addSu
@@ -2397,16 +2397,20 @@
 ed(e);%0A%09
+%09%09%7D%0A
 %09%09%09throw
@@ -2415,55 +2415,9 @@
 ow e
-;%0A%09%09%09%7D%0A%09%09%7D finally %7B%0A%09%09%09connection.disconnect()
+1
 ;%0A%09%09

fix http error handling