/*
* Copyright (C) 2015 Actor LLC. <https://actor.im>
*/
package im.actor.core.modules.messaging.actions;
import java.io.IOException;
import java.util.HashSet;
import im.actor.core.entity.Peer;
import im.actor.core.modules.ModuleContext;
import im.actor.core.modules.messaging.actions.entity.PlainCursor;
import im.actor.core.modules.messaging.actions.entity.PlainCursorsStorage;
import im.actor.core.modules.ModuleActor;
import im.actor.runtime.storage.SyncKeyValue;
public abstract class CursorActor extends ModuleActor {
private PlainCursorsStorage plainCursorsStorage;
private HashSet<Peer> inProgress = new HashSet<Peer>();
private long cursorId;
private SyncKeyValue keyValue;
public CursorActor(long cursorId, ModuleContext context) {
super(context);
this.cursorId = cursorId;
this.keyValue = context.getMessagesModule().getCursorStorage();
}
@Override
public void preStart() {
super.preStart();
plainCursorsStorage = new PlainCursorsStorage();
byte[] data = keyValue.get(cursorId);
if (data != null) {
try {
plainCursorsStorage = PlainCursorsStorage.fromBytes(data);
} catch (IOException e) {
e.printStackTrace();
}
}
for (PlainCursor cursor : plainCursorsStorage.getAllCursors()) {
if (cursor.getSortDate() < cursor.getPendingSortDate()) {
inProgress.add(cursor.getPeer());
perform(cursor.getPeer(), cursor.getPendingSortDate());
}
}
}
protected final void moveCursor(Peer peer, long date) {
PlainCursor cursor = plainCursorsStorage.getCursor(peer);
if (date <= cursor.getSortDate()) {
return;
}
if (date <= cursor.getPendingSortDate()) {
return;
}
date = Math.max(cursor.getPendingSortDate(), date);
plainCursorsStorage.putCursor(cursor.changePendingSortDate(date));
saveCursorState();
if (inProgress.contains(peer)) {
return;
}
inProgress.add(peer);
perform(peer, date);
}
protected final void onMoved(Peer peer, long date) {
inProgress.remove(peer);
PlainCursor cursor = plainCursorsStorage.getCursor(peer);
cursor = cursor.changeSortDate(Math.max(date, cursor.getSortDate()));
plainCursorsStorage.putCursor(cursor);
saveCursorState();
if (cursor.getSortDate() < cursor.getPendingSortDate()) {
inProgress.add(peer);
perform(peer, cursor.getPendingSortDate());
}
}
// Execution
protected abstract void perform(Peer peer, long date);
protected void onCompleted(Peer peer, long date) {
self().send(new OnCompleted(peer, date));
}
protected void onError(Peer peer, long date) {
// Ignore
}
private void saveCursorState() {
keyValue.put(cursorId, plainCursorsStorage.toByteArray());
}
@Override
public void onReceive(Object message) {
if (message instanceof OnCompleted) {
OnCompleted completed = (OnCompleted) message;
onMoved(completed.getPeer(), completed.getDate());
} else {
super.onReceive(message);
}
}
private static class OnCompleted {
private Peer peer;
private long date;
private OnCompleted(Peer peer, long date) {
this.peer = peer;
this.date = date;
}
public Peer getPeer() {
return peer;
}
public long getDate() {
return date;
}
}
}