package com.piusvelte.sonet.social;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import com.piusvelte.sonet.BuildConfig;
import com.piusvelte.sonet.R;
import com.piusvelte.sonet.Sonet;
import com.piusvelte.sonet.SonetHttpClient;
import com.piusvelte.sonet.provider.Entity;
import com.piusvelte.sonet.provider.Statuses;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import static com.piusvelte.sonet.Sonet.Saccess_token;
import static com.piusvelte.sonet.Sonet.Sbody;
import static com.piusvelte.sonet.Sonet.Scomments;
import static com.piusvelte.sonet.Sonet.ScreatedDate;
import static com.piusvelte.sonet.Sonet.Sid;
import static com.piusvelte.sonet.Sonet.Sitems;
import static com.piusvelte.sonet.Sonet.Sname;
import static com.piusvelte.sonet.Sonet.Sphoto;
import static com.piusvelte.sonet.Sonet.SsmallPhotoUrl;
import static com.piusvelte.sonet.Sonet.Stext;
import static com.piusvelte.sonet.Sonet.Stotal;
import static com.piusvelte.sonet.Sonet.Suser;
/**
* Created by bemmanuel on 2/15/15.
*/
public class Chatter extends Client {
private static final String CHATTER_URL_AUTHORIZE = "https://login.salesforce" +
".com/services/oauth2/authorize?response_type=token&display=touch&client_id=%s&redirect_uri=%s";
private static final String CHATTER_URL_ACCESS = "https://login.salesforce" +
".com/services/oauth2/token?grant_type=refresh_token&client_id=%s&refresh_token=%s";
private static final String CHATTER_URL_ME = "%s/services/data/v22.0/chatter/users/me";
private static final String CHATTER_URL_POST = "%s/services/data/v22.0/chatter/feeds/news/me/feed-items?text=%s";
private static final String CHATTER_URL_COMMENT = "%s/services/data/v22.0/chatter/feed-items/%s/comments?text=%s";
private static final String CHATTER_URL_FEED = "%s/services/data/v22.0/chatter/feeds/news/me/feed-items";
private static final String CHATTER_URL_LIKES = "%s/services/data/v22.0/chatter/feed-items/%s/likes";
private static final String CHATTER_URL_LIKE = "%s/services/data/v22.0/chatter/likes/%s";
private static final String CHATTER_URL_COMMENTS = "%s/services/data/v22.0/chatter/feed-items/%s/comments";
private static final String CHATTER_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
private static final String INSTANCE_URL = "instance_url";
private String mChatterInstance = null;
private String mChatterToken = null;
public Chatter(Context context, String token, String secret, String accountEsid, int network) {
super(context, token, secret, accountEsid, network);
}
@Nullable
@Override
public String getProfileUrl(@NonNull String esid) {
if (getChatterInstance()) {
return mChatterInstance + "/" + esid;
}
return null;
}
@Nullable
@Override
public String getProfilePhotoUrl() {
return getProfilePhotoUrl(mAccountEsid);
}
@Nullable
@Override
public String getProfilePhotoUrl(String esid) {
if (getChatterInstance()) {
Request request = new Request.Builder()
.url(String.format(CHATTER_URL_ME, mChatterInstance))
.addHeader("Authorization", "OAuth " + mChatterToken)
.build();
String httpRespnose = SonetHttpClient.getResponse(request);
if (!TextUtils.isEmpty(httpRespnose)) {
try {
JSONObject jobj = new JSONObject(httpRespnose);
return jobj.getJSONObject(Sphoto).getString(SsmallPhotoUrl);
} catch (JSONException e) {
if (BuildConfig.DEBUG) Log.d(mTag, "error parse chatter me: " + httpRespnose, e);
}
}
}
return null;
}
private boolean hasChatterInstance() {
return !TextUtils.isEmpty(mChatterInstance) && !TextUtils.isEmpty(mChatterToken);
}
private boolean getChatterInstance() {
if (!hasChatterInstance()) {
String response = null;
String url = String.format(CHATTER_URL_ACCESS, BuildConfig.CHATTER_KEY, mToken);
OkHttpClient client = SonetHttpClient.getOkHttpClientInstance();
Request request = new Request.Builder()
.url(url)
.post(null)
.build();
try {
response = client.newCall(request)
.execute()
.body()
.string();
} catch (IOException e) {
if (BuildConfig.DEBUG) {
Log.e(mTag, "request error; url=" + url, e);
}
}
if (!TextUtils.isEmpty(response)) {
try {
JSONObject jobj = new JSONObject(response);
if (jobj.has(INSTANCE_URL) && jobj.has(Saccess_token)) {
mChatterInstance = jobj.getString(INSTANCE_URL);
mChatterToken = jobj.getString(Saccess_token);
return hasChatterInstance();
}
} catch (JSONException e) {
if (BuildConfig.DEBUG) Log.e(mTag, e.toString());
}
}
}
return false;
}
@Nullable
@Override
public Set<String> getNotificationStatusIds(long account, String[] notificationMessage) {
return null;
}
@Nullable
@Override
public String getFeedResponse(int status_count) {
if (getChatterInstance()) {
Request request = new Request.Builder()
.url(String.format(CHATTER_URL_FEED, mChatterInstance))
.addHeader("Authorization", "OAuth " + mChatterToken)
.build();
return SonetHttpClient.getResponse(request);
}
return null;
}
@Nullable
@Override
public JSONArray parseFeed(@NonNull String response) throws JSONException {
return new JSONObject(response).getJSONArray(Sitems);
}
@Nullable
@Override
public void addFeedItem(@NonNull JSONObject item,
boolean display_profile,
boolean time24hr,
int appWidgetId,
long account,
Set<String> notificationSids,
String[] notificationMessage,
boolean doNotify) throws JSONException {
ArrayList<String[]> links = new ArrayList<>();
JSONObject friendObj = item.getJSONObject(Suser);
JSONObject photo = friendObj.getJSONObject(Sphoto);
JSONObject comments = item.getJSONObject(Scomments);
long date = parseDate(item.getString(ScreatedDate), CHATTER_DATE_FORMAT);
addStatusItem(date,
friendObj.getString(Sname),
display_profile ? photo.getString(SsmallPhotoUrl) + "?oauth_token=" + mChatterToken : null,
String.format(getString(R.string.messageWithCommentCount), item.getJSONObject(Sbody).getString(Stext), comments.getInt(Stotal)),
time24hr,
appWidgetId,
account,
item.getString(Sid),
friendObj.getString(Sid),
links
);
}
@Nullable
@Override
public void getNotificationMessage(long account, String[] notificationMessage) {
// NO-OP
}
@Override
public void getNotifications(long account, String[] notificationMessage) {
// NO-OP
}
@Override
public boolean createPost(String message, String placeId, String latitude, String longitude, String photoPath, String[] tags) {
if (getChatterInstance()) {
Request request = new Request.Builder()
.url(String.format(CHATTER_URL_POST, mChatterInstance, Uri.encode(message)))
.addHeader("Authorization", "OAuth " + mChatterToken)
.post(null)
.build();
return SonetHttpClient.request(request);
}
return false;
}
@Override
public boolean isLikeable(String statusId) {
return true;
}
@Override
public boolean isLiked(String statusId, String accountId) {
if (getChatterInstance()) {
Request request = new Request.Builder()
.url(String.format(CHATTER_URL_LIKES, mChatterInstance, statusId))
.addHeader("Authorization", "OAuth " + mChatterToken)
.build();
String response = SonetHttpClient.getResponse(request);
if (!TextUtils.isEmpty(response)) {
try {
JSONObject jobj = new JSONObject(response);
if (jobj.getInt(Stotal) > 0) {
JSONArray likes = jobj.getJSONArray("likes");
for (int i = 0, i2 = likes.length(); i < i2; i++) {
JSONObject like = likes.getJSONObject(i);
if (like.getJSONObject(Suser).getString(Sid).equals(accountId)) {
// TODO need like id to unlike = like.getString(Sid);
return true;
}
}
}
} catch (JSONException e) {
if (BuildConfig.DEBUG) Log.e(mTag, e.toString());
}
}
}
return false;
}
@Override
public boolean likeStatus(String statusId, String accountId, boolean doLike) {
Request.Builder builder = new Request.Builder();
if (doLike) {
builder.url(String.format(CHATTER_URL_LIKES, mChatterInstance, statusId));
builder.post(null);
} else {
builder.url(String.format(CHATTER_URL_LIKE, mChatterInstance, "" /* TODO replace this string with the like id from isLiked */));
builder.delete();
}
builder.addHeader("Authorization", "OAuth " + mChatterToken);
return SonetHttpClient.request(builder.build());
}
@Override
public String getLikeText(boolean isLiked) {
return getString(isLiked ? R.string.unlike : R.string.like);
}
@Override
public boolean isCommentable(String statusId) {
return true;
}
@Override
public String getCommentPretext(String accountId) {
return null;
}
@Override
public void onDelete() {
}
@Nullable
@Override
public String getCommentsResponse(String statusId) {
if (getChatterInstance()) {
Request request = new Request.Builder()
.url(String.format(CHATTER_URL_COMMENTS, mChatterInstance, statusId))
.addHeader("Authorization", "OAuth " + mChatterToken)
.build();
return SonetHttpClient.getResponse(request);
}
return null;
}
@Nullable
@Override
public JSONArray parseComments(@NonNull String response) throws JSONException {
JSONObject chats = new JSONObject(response);
if (chats.getInt(Stotal) > 0) {
return chats.getJSONArray(Scomments);
}
return null;
}
@Nullable
@Override
public HashMap<String, String> parseComment(@NonNull String statusId, @NonNull JSONObject jsonComment, boolean time24hr) throws JSONException {
HashMap<String, String> commentMap = new HashMap<String, String>();
commentMap.put(Statuses.SID, jsonComment.getString(Sid));
commentMap.put(Entity.FRIEND, jsonComment.getJSONObject(Suser).getString(Sname));
commentMap.put(Statuses.MESSAGE, jsonComment.getJSONObject(Sbody).getString(Stext));
commentMap.put(Statuses.CREATEDTEXT, Sonet.getCreatedText(parseDate(jsonComment.getString(ScreatedDate), CHATTER_DATE_FORMAT), time24hr));
// TODO does this have the like id for unliking?
commentMap.put(getString(R.string.like), "");
return commentMap;
}
@Override
public LinkedHashMap<String, String> getLocations(String latitude, String longitude) {
return null;
}
@Override
public boolean sendComment(@NonNull String statusId, @NonNull String message) {
if (getChatterInstance()) {
Request request = new Request.Builder()
.url(String.format(CHATTER_URL_COMMENT, mChatterInstance, statusId, Uri.encode(message)))
.post(null)
.addHeader("Authorization", "OAuth " + mChatterToken)
.build();
return SonetHttpClient.request(request);
}
return false;
}
@Override
public List<HashMap<String, String>> getFriends() {
return null;
}
@Override
String getApiKey() {
return BuildConfig.CHATTER_KEY;
}
@Override
String getApiSecret() {
return BuildConfig.CHATTER_SECRET;
}
@Nullable
@Override
public Uri getCallback() {
return Uri.parse("sonet://chatter");
}
@Override
String getRequestUrl() {
return null;
}
@Override
String getAccessUrl() {
return null;
}
@Override
String getAuthorizeUrl() {
return null;
}
@Override
public String getCallbackUrl() {
return null;
}
@Override
public MemberAuthentication getMemberAuthentication(@NonNull String authenticatedUrl) {
// get the access_token
Uri uri = Uri.parse(authenticatedUrl);
String token = uri.getQueryParameter(Saccess_token);
String refresh_token = uri.getQueryParameter("refresh_token");
String instance_url = uri.getQueryParameter("instance_url");
Request request = new Request.Builder()
.url(String.format(CHATTER_URL_ME, instance_url))
.addHeader("Authorization", "OAuth " + token)
.build();
String httpRespnose = SonetHttpClient.getResponse(request);
if (!TextUtils.isEmpty(httpRespnose)) {
try {
JSONObject jobj = new JSONObject(httpRespnose);
if (jobj.has(Sname) && jobj.has(Sid)) {
MemberAuthentication memberAuthentication = new MemberAuthentication();
memberAuthentication.username = jobj.getString(Sname);
memberAuthentication.token = refresh_token;
memberAuthentication.secret = "";
memberAuthentication.expiry = 0;
memberAuthentication.network = mNetwork;
memberAuthentication.id = jobj.getString(Sid);
return memberAuthentication;
}
} catch (JSONException e) {
if (BuildConfig.DEBUG) Log.d(mTag, "error parse chatter me: " + httpRespnose, e);
}
}
return null;
}
@Nullable
@Override
public String getAuthUrl() {
return String.format(CHATTER_URL_AUTHORIZE, BuildConfig.CHATTER_KEY, getCallback().toString());
}
}