package de.bitdroid.flooding.ods;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public final class RestCall {

	public enum RequestType {
		GET("GET"),
		POST("POST"),
		UPDATE("UPDATE"),
		DELETE("DELETE");

		private final String type;
		RequestType(String type) { this.type = type; }

		@Override
		public String toString() { return type; }
	}


	private final RequestType requestType;
	private final String baseUrl;
	private final List<String> paths;
	private final Map<String, String> parameters;
	private final Map<String, String> headers;


	private RestCall(
				RequestType requestType,
				String baseUrl,
				List<String> paths,
				Map<String, String> parameters,
				Map<String, String> headers) {
		
		this.requestType = requestType;
		this.baseUrl = baseUrl;
		this.paths = paths;
		this.parameters = parameters;
		this.headers = headers;
	}


	public String execute() throws RestException {

		StringBuilder urlBuilder = new StringBuilder(baseUrl);

		// format paths
		for (String path : paths) urlBuilder.append("/" + path);

		// format params
		if (parameters.size() != 0) {
			urlBuilder.append("?");
			boolean firstKey = true;
			for (String key : parameters.keySet()) {
				if (!firstKey) urlBuilder.append("&");
				firstKey = false;

				urlBuilder.append(key + "=" + parameters.get(key));
			}
		}


		// create connection
		HttpURLConnection conn = null;
		OutputStream outputStream = null;
		BufferedReader dataReader = null;
		try {
			URL url = new URL(urlBuilder.toString());

			conn = (HttpURLConnection) url.openConnection();
			for (String key : headers.keySet()) {
				conn.setRequestProperty(key, headers.get(key));
			}
			conn.setUseCaches(false);
			conn.setRequestMethod(requestType.toString());

			int responseCode = conn.getResponseCode();
			if (responseCode != HttpURLConnection.HTTP_CREATED
					&& responseCode != HttpURLConnection.HTTP_OK
					&& responseCode != HttpURLConnection.HTTP_ACCEPTED)
				throw new RestException(responseCode);

			dataReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			StringBuilder dataBuilder = new StringBuilder();
			String line;
			while ((line = dataReader.readLine()) != null)
				dataBuilder.append(line);

			return dataBuilder.toString();
			
		} catch (IOException ie) {
			throw new RestException(ie);

		} finally {
			try {
				if (outputStream != null) outputStream.close();
				if (dataReader != null) dataReader.close();
			} catch (IOException e) { }

			if (conn != null) conn.disconnect();
		}
	}

	

	public static class Builder {
		private final RequestType requestType;
		private final String baseUrl;
		private final List<String> paths = new LinkedList<String>();
		private final Map<String, String> parameters = new HashMap<String, String>();
		private final Map<String, String> headers = new HashMap<String, String>();
		private boolean built = false;

		public Builder(final RequestType requestType, final String baseUrl) {
			if (requestType == null || baseUrl == null)
				throw new NullPointerException("params cannot be null");

			this.requestType = requestType;
			this.baseUrl = baseUrl;
		}

		public Builder path(String path) {
			if (path == null) throw new NullPointerException("path cannot be null");
			if (built) throw new IllegalStateException("already built");
			paths.add(path);
			return this;
		}

		public Builder parameter(String key, String value) {
			if (key == null || value == null) throw new NullPointerException("params cannot be null");
			if (built) throw new IllegalStateException("already built");
			parameters.put(key, value);
			return this;
		}

		public Builder header(String key, String value) {
			if (key == null || value == null) throw new NullPointerException("params cannot be null");
			if (built) throw new IllegalStateException("already built");
			headers.put(key, value);
			return this;
		}

		public RestCall build() {
			if (built) throw new IllegalStateException("already built");
			built = true;
			return new RestCall(requestType, baseUrl, paths, parameters, headers);
		}
	}

}

@@ -307,16 +307,56 @@
 l.Map;%0A%0A
+import de.bitdroid.flooding.utils.Log;%0A%0A
 public f
@@ -1593,16 +1593,67 @@
 %09%7D%0A%09%09%7D%0A%0A
+%09%09Log.debug(%22Fetching %22 + urlBuilder.toString());%0A%0A
 %0A%09%09// cr

debug msg when fetching data