package org.commcare.android.nsd;
import org.commcare.network.HttpRequestGenerator;
import org.javarosa.core.io.StreamsUtil;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
/**
* API wrapper class for services provided by CommCare micronodes.
*
* Micronodes are HTTP services which provide access to CommCare user and applicaiton level data
* across local networks.
*
* Created by ctsims on 2/19/2016.
*/
public class MicroNode {
private final String serviceUrlRoot;
private ArrayList<AppManifest> availableApplications;
public MicroNode(String uri) {
serviceUrlRoot = uri;
}
public ArrayList<AppManifest> getAvailableApplications() {
if (availableApplications == null) {
availableApplications = new ArrayList<>();
try {
InputStream is = new BufferedInputStream(
HttpRequestGenerator.buildNoAuthGenerator().simpleGet(new URL(serviceUrlRoot + "/apps/manifest")));
byte[] manifest = StreamsUtil.inputStreamToByteArray(is);
JSONObject object = new JSONObject(new String(manifest));
JSONArray array = object.getJSONArray("applications");
for (int i = 0; i < array.length(); ++i) {
JSONObject app = array.getJSONObject(i);
AppManifest appRecord = AppManifest.fromJSON(app);
availableApplications.add(appRecord);
}
} catch (IOException | JSONException e) {
e.printStackTrace();
}
}
return availableApplications;
}
/**
* Given a unique app ID, return a local hub manifest for a matching record, if available.
* If no availalbe apps match the id, null will be returned.
*/
public AppManifest getManifestForAppId(String appId) {
ArrayList<AppManifest> apps = getAvailableApplications();
for (AppManifest app : apps) {
if (appId.equals(app.getId())) {
return app;
}
}
return null;
}
public static class AppManifest {
final private String name;
final private String localUrl;
final private String id;
public AppManifest(String name, String localUrl, String id) {
this.name = name;
this.localUrl = localUrl;
this.id = id;
}
public static AppManifest fromJSON(JSONObject app) throws JSONException {
String appId = app.has("app_guid") ? app.getString("app_guid") :
getAppIdFromCCZHack(app.getString("download_url"));
return new AppManifest(app.getString("name"), app.getString("profile_url"),
appId);
}
public String getName() {
return name;
}
public String getLocalUrl() {
return localUrl;
}
public String getId() {
return id;
}
}
// Replace as soon as the manifest format contains this info
private static String getAppIdFromCCZHack(String cczUrl) {
if (cczUrl.contains("app_id=")) {
String[] results = cczUrl.split("app_id=");
return results.length < 2 ? null : results[1];
} else {
return null;
}
}
}