package org.greengin.sciencetoolkit.common.logic.remote;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Vector;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.greengin.sciencetoolkit.common.ui.base.RemoteCapableActivity;
import org.greengin.sciencetoolkit.common.ui.base.WebViewLoginActivity;
import org.json.JSONArray;
import org.json.JSONObject;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import android.webkit.CookieSyncManager;
public class RemoteApi {
public static final String REMOTE_LOGIN_EVENT_FILTER = "REMOTE_EVENT_FILTER";
public static final String PROTOCOL = "http";
public static final String DOMAIN = "www.nquire-it.org";
public static final String PATH = "/";
public static final String WELCOME_PATH = "social/welcome";
private static RemoteApi instance;
public static RemoteApi get() {
return instance;
}
public static void init(Context applicationContext) {
RemoteApi.instance = new RemoteApi(applicationContext);
}
Context applicationContext;
boolean logged;
String token;
String username;
DefaultHttpClient httpClient;
Vector<RemoteAction> queue;
boolean running;
ReentrantLock runningLock;
public String getUsername() {
return username;
}
public boolean isLogged() {
return logged;
}
private RemoteApi(Context applicationContext) {
this.applicationContext = applicationContext;
this.httpClient = new DefaultHttpClient();
this.logged = false;
queue = new Vector<RemoteAction>();
running = false;
runningLock = new ReentrantLock();
CookieSyncManager.createInstance(applicationContext);
}
public void request(RemoteCapableActivity activity, RemoteAction action) {
Log.d("stk remote", "request " + action.getClass().getSimpleName());
Log.d("stk remote", "request " + logged + " " + running);
queue.add(action);
if (logged) {
if (!running) {
executeOne();
}
} else {
tryToLogin(activity);
}
}
public void resumeRequests(RemoteCapableActivity activity) {
Log.d("stk remote", "resume requests " + activity.getClass().getName());
if (queue.size() > 0 && !running) {
if (logged) {
executeOne();
}
}
}
public void loginActionComplete() {
if (!logged) {
for (RemoteAction action : queue) {
action.error(-1, "nologin");
}
queue.clear();
}
}
private void executeOne() {
Log.d("stk remote", "execute one");
try {
running = true;
RemoteAction action = queue.remove(0);
new ActionThread(action).start();
} catch (Exception e) {
running = false;
}
}
public void setSession(String session) {
Log.d("stk remote", "set session");
BasicClientCookie cookie = new BasicClientCookie("JSESSIONID", session);
cookie.setDomain(DOMAIN);
cookie.setPath(PATH);
httpClient.getCookieStore().addCookie(cookie);
new ActionThread(new GetTokenAction(true)).start();
}
public void logout() {
if (logged) {
new ActionThread(new GetTokenAction(false)).start();
}
}
public void tryToLogin(RemoteCapableActivity activity) {
Log.d("stk remote", "login requested");
Intent intent = new Intent(activity, WebViewLoginActivity.class);
activity.startActivity(intent);
}
private class ActionThread extends Thread {
RemoteAction action;
public ActionThread(RemoteAction action) {
this.action = action;
}
public void run() {
Log.d("stk remote", "start: " + action.getClass().getSimpleName());
try {
HttpRequestBase[] requests = action.createRequests("http://" + DOMAIN + PATH + "api/");
for (int i = 0; i < requests.length; i++) {
requests[i].addHeader("nquire-it-token", token);
action.aboutToRun(i);
try {
HttpResponse response = httpClient.execute(requests[i]);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line;
StringBuffer answer = new StringBuffer();
while ((line = reader.readLine()) != null) {
answer.append(line).append('\n');
}
reader.close();
response.getEntity().consumeContent();
action.result(i, answer.toString());
} catch (Exception e) {
e.printStackTrace();
action.error(i, e.getMessage());
}
}
} catch (Exception e) {
e.printStackTrace();
}
Log.d("stk remote", "end: " + action.getClass().getSimpleName());
executeOne();
}
}
private class GetTokenAction extends RemoteJsonAction {
boolean login;
public GetTokenAction(boolean login) {
this.login = login;
}
@Override
public HttpRequestBase[] createRequests(String urlBase) {
HttpRequestBase request = login ? new HttpGet(urlBase + "security/status") : new HttpPost(urlBase + "security/logout");
return new HttpRequestBase[] { request };
}
@Override
public void result(int request, JSONObject result, JSONArray array) {
try {
token = result.getString("token");
logged = result.getBoolean("logged");
username = logged ? result.getJSONObject("profile").getString("username") : null;
} catch (Exception e) {
logged = false;
token = null;
username = null;
}
Log.d("stk remote", "logged: " + logged + " " + token);
Log.d("stk remote", result.toString());
Intent i = new Intent(REMOTE_LOGIN_EVENT_FILTER);
LocalBroadcastManager.getInstance(applicationContext).sendBroadcast(i);
loginActionComplete();
}
@Override
public void error(int request, String msg) {
loginActionComplete();
}
}
}