package org.ntlab.radishforandroidstudio.framework.network;


import android.os.AsyncTask;
import android.util.Log;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

abstract public class HttpAsyncConnection extends AsyncTask<Void, Void, String> {

	private HttpURLConnection conn = null;
	private String baseUrl = null;
	private String queryParams = "";
	private String pathParams = "";
	private String formParams = "";
	private CallBack callBack = null;


	private String method;
	private static String clientSessionID = null;

	public HttpAsyncConnection(String url) {
		baseUrl = url;
	}


	public void doPost() {
		setMethod("POST");
		execute();
	}

	public void doGet() {
		setMethod("GET");
		execute();
	}

	public void doPut() {
		setMethod("PUT");
		execute();
	}

	public void doDelete() {
		setMethod("DELETE");
		execute();
	}

	public void setCallBack(CallBack callBack) {
		this.callBack = callBack;
	}

	private void setMethod(String method) {
		this.method = method;
	}

	@Override
	protected String doInBackground(Void... urls) {
		doAnything();
		return doReceive();
	}

	/* (non-Javadoc)
	 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
	 */
	public void onPostExecute(String response) {
		try {
			if (callBack != null) callBack.onResponse(response);
		} catch (Exception e) {
			// TODO: handle exception
			Log.d("error", "�G���[�I");
		}
	}


	// request
	public void doAnything() {
		try {
			if(conn == null) {
				if(queryParams == null || queryParams.length() == 0){
					conn = (HttpURLConnection) new URL(baseUrl + pathParams).openConnection();
				} else {
					conn = (HttpURLConnection) new URL(baseUrl + pathParams + "?" + queryParams).openConnection();
				}
			}
			conn.setReadTimeout(10000 /* milliseconds */);
			conn.setConnectTimeout(15000 /* milliseconds */);
			// POST or GET or PUT or DELETE
			conn.setRequestMethod(method);

			if (formParams.length() > 0) {
				conn.setDoOutput(true);
				if(clientSessionID != null) {
					conn.setRequestProperty("Cookie", clientSessionID);
				}
				OutputStream out = conn.getOutputStream();
				out.write(formParams.getBytes("UTF-8"));
				out.flush();
				out.close();
				formParams = "";
			}
			pathParams = "";
			queryParams = "";

			conn.connect();

			if(clientSessionID == null ) {
				clientSessionID = conn.getHeaderField("Set-Cookie");

			}
		} catch (IOException e) {
			notConnection();
			e.printStackTrace();
		}
	}

	// response
	public String doReceive() {
		BufferedReader reader;
		try {
			reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line;
			StringBuilder builder = new StringBuilder();
			while((line = reader.readLine()) != null)
				builder.append(line);
			reader.close();
			if (conn != null) conn.disconnect();
			return builder.toString();
		} catch (IOException e) {
			e.printStackTrace();
			if (conn != null) conn.disconnect();
			return null;
		}

	}

	public void notConnection(){};

	/**
	 *  param set
	 * @param key
	 * @param value
	 */
	public void addQueryParam(String key, String value) {
		if(queryParams.length() > 0) {
			queryParams += ("&");
		}
		queryParams += (key + "=" + value);
	}

	public void addFormParam(String key, String value) {
		if(formParams.length() > 0) {
			formParams += "&";
		}
		formParams += (key + "=" + value);
	}

	public void addPathParam(String param){
		pathParams += "/" + param;
	}
}
