package com.bigcommerce.api;

import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.codec.binary.Base64;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class Connection {

	String username;
	String password;
	String storeUrl;

	private InputStream responseStream;
	private HttpURLConnection transport;

	public Connection(String storeUrl, String username, String apikey) {
		this.storeUrl = storeUrl;
		this.username = username;
		this.password = apikey;
	}

	/**
	 * Get encoded string representing HTTP Basic authorization credentials for
	 * the request.
	 */
	private String getBasicAuthHeader() {
		String token = this.username + ":" + this.password;
		byte[] encodedToken = Base64.encodeBase64(token.getBytes());
		return "Basic " + new String(encodedToken);
	}

	/**
	 * Create the HTTP connection transport to specified URL path.
	 */
	private HttpURLConnection createTransport(String path, String verb)
			throws java.io.IOException {
		URL url = new URL(this.storeUrl + path);
		HttpURLConnection transport = (HttpURLConnection) url.openConnection();
		transport.setRequestMethod(verb);
		transport
				.setRequestProperty("Authorization", this.getBasicAuthHeader());
		return transport;
	}

	/**
	 * Make an HTTP GET request to the given endpoint.
	 */
	public Connection get(String path) {
		if (transport != null) {
			transport.disconnect();
		}

		try {

			transport = this.createTransport(path, "GET");
			this.responseStream = transport.getInputStream();

		} catch (Exception e) {

			System.out.print(e.toString());

		}

		return this;
	}

	/**
	 * Close any existing HTTP connection.
	 */
	private void closeExistingConnection() {
		if (transport != null) {
			transport.disconnect();
			transport = null;
		}
	}

	/**
	 * Close any open connection.
	 */
	public void close() {
		closeExistingConnection();
	}

	/**
	 * Make an HTTP POST request to the given endpoint.
	 */
	public boolean post(String path, String data) {

		closeExistingConnection();

		try {
			transport = this.createTransport(path, "POST");
			transport.setDoOutput(true);

			OutputStreamWriter post = new OutputStreamWriter(
					transport.getOutputStream());
			post.write(data);
			post.flush();
			post.close();

			this.responseStream = transport.getInputStream();

		} catch (Exception e) {
			System.out.print(e.toString());
		}

		return false;
	}

	/**
	 * Make an HTTP PUT request to the given endpoint.
	 */
	public boolean put(String path, String data) {
		closeExistingConnection();

		try {
			transport = this.createTransport(path, "PUT");
			this.responseStream = transport.getInputStream();
			return true;
		} catch (Exception e) {
			System.out.print(e.toString());
		}

		return false;
	}

	/**
	 * Make an HTTP DELETE request to the given endpoint.
	 */
	public boolean delete(String path) {
		closeExistingConnection();

		try {
			transport = this.createTransport(path, "DELETE");
			return true;
		} catch (Exception e) {
			System.out.print(e.toString());
		}

		return false;
	}

	/**
	 * String representation of the raw HTTP response body.
	 */
	public String asString() {
		String responseBody = "";

		try {
			StringBuffer body = new StringBuffer();
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					this.responseStream, "UTF-8"));
			String inputLine;
			while ((inputLine = reader.readLine()) != null) {
				body.append(inputLine);
			}
			reader.close();
			responseBody = body.toString();

		} catch (Exception e) {
			System.out.print(e.toString());
		} finally {
			closeExistingConnection();
		}

		return responseBody;
	}

	/**
	 * XML representation of the HTTP response.
	 */
	public Element asXml() {
		Element responseXml = null;

		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document document = builder.parse(this.responseStream);
			responseXml = document.getDocumentElement();

		} catch (Exception e) {
			System.out.print(e.toString());
		} finally {
			closeExistingConnection();
		}

		return responseXml;
	}

}
@@ -1772,32 +1772,34 @@
 System.out.print
+ln
 (e.toString());%0A
@@ -2565,32 +2565,34 @@
 System.out.print
+ln
 (e.toString());%0A
@@ -2822,57 +2822,397 @@
 %09%09%09t
-his.responseStream = transport.getInputStream();%0A
+ransport.setDoOutput(true);%0A%09%09    transport.setRequestProperty(%22Content-Type%22, %22application/json%22);%0A%0A%09%09%09OutputStreamWriter put = new OutputStreamWriter(%0A%09%09%09%09%09transport.getOutputStream());%0A%09%09%09put.write(data);%0A%09%09%09put.flush();%0A%09%09%09put.close();%0A%09%09%09%0A%09%09%09this.responseStream = transport.getInputStream();%0A%09%09%09int result = transport.getResponseCode(); %0A%09%09%09if(result == HttpURLConnection.HTTP_OK) %7B%0A%09
 %09%09%09r
@@ -3215,32 +3215,37 @@
 %09%09%09return true;%0A
+%09%09%09%7D%0A
 %09%09%7D catch (Excep
@@ -3265,32 +3265,34 @@
 System.out.print
+ln
 (e.toString());%0A
@@ -3563,32 +3563,34 @@
 System.out.print
+ln
 (e.toString());%0A
@@ -4094,32 +4094,34 @@
 System.out.print
+ln
 (e.toString());%0A
@@ -4608,16 +4608,18 @@
 ut.print
+ln
 (e.toStr
@@ -4702,8 +4702,9 @@
 l;%0A%09%7D%0A%0A%7D
+%0A

Update (PUT) a resource API call is added.