package com.robonobo.core.service;
import static com.robonobo.common.util.TimeUtil.*;
import java.util.*;
import java.util.Map.Entry;
import com.robonobo.core.api.model.Comment;
import com.robonobo.core.api.model.User;
import com.robonobo.core.metadata.*;
public class CommentService extends AbstractService {
Map<String, Date> lastFetched = new HashMap<String, Date>();
Map<String, Map<Comment, Boolean>> cmtsByResId = new HashMap<String, Map<Comment, Boolean>>();
private AbstractMetadataService metadata;
private DbService db;
private EventService events;
public CommentService() {
addHardDependency("core.metadata");
addHardDependency("core.db");
addHardDependency("core.events");
}
@Override
public String getName() {
return "Comment service";
}
@Override
public String getProvides() {
return "core.comments";
}
@Override
public void startup() throws Exception {
metadata = rbnb.getMetadataService();
db = rbnb.getDbService();
events = rbnb.getEventService();
}
private synchronized void storeComments(String resourceId, Map<Comment, Boolean> cMap) {
if (cmtsByResId.containsKey(resourceId))
cmtsByResId.get(resourceId).putAll(cMap);
else
cmtsByResId.put(resourceId, cMap);
}
public void newCommentForPlaylist(final long playlistId, long parentId, String text, final CommentCallback cb) {
Comment c = new Comment();
final String resId = "playlist:" + playlistId;
c.setResourceId(resId);
c.setParentId(parentId);
c.setUserId(rbnb.getUserService().getMyUser().getUserId());
c.setText(text);
metadata.newComment(c, new CommentCallback() {
public void success(Comment c) {
// Fire the callback first, then our event
cb.success(c);
Map<Comment, Boolean> flarp = new HashMap<Comment, Boolean>();
flarp.put(c, false);
storeComments(resId, flarp);
events.fireGotPlaylistComments(playlistId, false, flarp);
db.markCommentsAsSeen(flarp.keySet());
}
public void error(long commentId, Exception ex) {
cb.error(commentId, ex);
}
});
}
public void newCommentForLibrary(final long userId, long parentId, String text, final CommentCallback cb) {
final User me = rbnb.getUserService().getMyUser();
Comment c = new Comment();
final String resId = "library:" + userId;
c.setResourceId(resId);
c.setParentId(parentId);
c.setUserId(me.getUserId());
c.setText(text);
metadata.newComment(c, new CommentCallback() {
public void success(Comment c) {
cb.success(c);
Map<Comment, Boolean> flarp = new HashMap<Comment, Boolean>();
flarp.put(c, false);
storeComments(resId, flarp);
events.fireGotLibraryComments(userId, false, flarp);
db.markCommentsAsSeen(flarp.keySet());
}
public void error(long commentId, Exception ex) {
cb.error(commentId, ex);
}
});
}
public Map<Comment, Boolean> getExistingComments(String resourceId) {
Map<Comment, Boolean> result = new HashMap<Comment, Boolean>();
synchronized (this) {
if (cmtsByResId.containsKey(resourceId))
result.putAll(cmtsByResId.get(resourceId));
}
return result;
}
public void markAllCommentsAsSeen(String resourceId) {
List<Comment> cl = new ArrayList<Comment>();
synchronized (this) {
if (cmtsByResId.containsKey(resourceId)) {
for (Entry<Comment, Boolean> ent : cmtsByResId.get(resourceId).entrySet()) {
ent.setValue(false);
cl.add(ent.getKey());
}
}
}
db.markCommentsAsSeen(cl);
}
public void deleteComment(Comment c, final CommentCallback cb) {
synchronized (this) {
if (cmtsByResId.containsKey(c.getResourceId()))
cmtsByResId.get(c.getResourceId()).remove(c);
}
metadata.deleteComment(c.getCommentId(), cb);
}
public void fetchCommentsForPlaylist(final long playlistId) {
final String resId = "playlist:" + playlistId;
final Date fetchTime = now();
metadata.getAllComments("playlist", playlistId, lastFetched.get(resId), new AllCommentsCallback() {
public void success(List<Comment> pl) {
if (pl.size() > 0) {
Map<Comment, Boolean> cNewMap = new HashMap<Comment, Boolean>();
boolean anyUnseen = false;
for (Comment c : pl) {
boolean unseen = !db.haveSeenComment(c.getCommentId());
if (unseen)
anyUnseen = true;
cNewMap.put(c, unseen);
}
storeComments(resId, cNewMap);
log.debug("Fetched " + pl.size() + " comments for playlist " + playlistId);
events.fireGotPlaylistComments(playlistId, anyUnseen, cNewMap);
}
lastFetched.put(resId, fetchTime);
}
public void error(long itemId, Exception ex) {
log.error("Error fetching comments for playlist " + itemId, ex);
}
});
}
public void fetchCommentsForLibrary(final long userId) {
final String resId = "library:" + userId;
final Date fetchTime = now();
metadata.getAllComments("library", userId, lastFetched.get(resId), new AllCommentsCallback() {
public void success(List<Comment> pl) {
if (pl.size() > 0) {
Map<Comment, Boolean> cNewMap = new HashMap<Comment, Boolean>();
boolean anyUnread = false;
for (Comment c : pl) {
boolean unread = !db.haveSeenComment(c.getCommentId());
if(unread)
anyUnread = true;
cNewMap.put(c, unread);
}
storeComments(resId, cNewMap);
log.debug("Fetched " + pl.size() + " comments for library " + userId);
events.fireGotLibraryComments(userId, anyUnread, cNewMap);
}
lastFetched.put(resId, fetchTime);
}
public void error(long itemId, Exception ex) {
log.error("Error fetching comments for library " + itemId, ex);
}
});
}
@Override
public void shutdown() throws Exception {
}
}