package com.mogujie.tt.imlib;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import android.content.Intent;
import com.mogujie.tt.config.ProtocolConstant;
import com.mogujie.tt.config.SysConstant;
import com.mogujie.tt.entity.RecentInfo;
import com.mogujie.tt.imlib.network.SocketThread;
import com.mogujie.tt.imlib.proto.ChangeTempGroupMemberPacket;
import com.mogujie.tt.imlib.proto.ContactEntity;
import com.mogujie.tt.imlib.proto.CreateTempGroupPacket;
import com.mogujie.tt.imlib.proto.GroupEntity;
import com.mogujie.tt.imlib.proto.GroupPacket;
import com.mogujie.tt.imlib.proto.GroupUnreadMsgPacket;
import com.mogujie.tt.imlib.proto.UnreadMsgGroupListPacket;
import com.mogujie.tt.imlib.utils.DumpUtils;
import com.mogujie.tt.imlib.utils.IMContactHelper;
import com.mogujie.tt.imlib.utils.IMUIHelper;
import com.mogujie.tt.log.Logger;
import com.mogujie.tt.packet.base.DataBuffer;
import com.mogujie.tt.packet.base.Header;
import com.mogujie.tt.utils.pinyin.PinYin;
public class IMGroupManager extends IMManager {
public static final int ADD_CHANGE_MEMBER_TYPE = 0;
public static final int REMOVE_CHANGE_MEMBER_TYPE = 1;
public static String getChangeMemberTypeString(int changeType) {
if (changeType == ADD_CHANGE_MEMBER_TYPE) {
return "tempgroup#adding members";
} else if (changeType == REMOVE_CHANGE_MEMBER_TYPE) {
return "tempgroup#removing members";
} else {
return "tempgroup#no such type";
}
}
private static IMGroupManager inst;
public static IMGroupManager instance() {
synchronized (IMGroupManager.class) {
if (inst == null) {
inst = new IMGroupManager();
}
return inst;
}
}
private Logger logger = Logger.getLogger(IMGroupManager.class);
private Map<String, GroupEntity> groups = new ConcurrentHashMap<String, GroupEntity>();
private boolean groupReady = false;
private boolean tempGroupReady = false;
private boolean unreadMsgGroupListReady = false;
private List<UnreadMsgGroupListPacket.PacketResponse.Entity> unreadMsgGroupList;
public Map<String, GroupEntity> getGroups() {
return groups;
}
public List<GroupEntity> getNormalGroupList() {
List<GroupEntity> normalGroupList = new ArrayList<GroupEntity>();
for (Entry<String, GroupEntity> entry : groups.entrySet()) {
GroupEntity group = entry.getValue();
if (group == null) {
continue;
}
if (group.type == IMSession.SESSION_GROUP) {
normalGroupList.add(group);
}
}
return normalGroupList;
}
public void setGroups(Map<String, GroupEntity> groups) {
this.groups = groups;
}
public GroupEntity findGroup(String groupId) {
logger.d("group#findGroup groupId:%s", groupId);
return groups.get(groupId);
}
public List<ContactEntity> getGroupMembers(String groupId) {
logger.d("group#getGroupMembers groupId:%s", groupId);
GroupEntity group = findGroup(groupId);
if (group == null) {
logger.e("group#no such group id:%s", groupId);
return null;
}
ArrayList<ContactEntity> memberList = new ArrayList<ContactEntity>();
for (String id : group.memberIdList) {
ContactEntity contact = IMContactManager.instance().findContact(id);
if (contact == null) {
logger.e("group#no such contact id:%s", id);
continue;
}
memberList.add(contact);
}
return memberList;
}
public void fetchGroupList() {
logger.d("group#fetchGroupList");
reqGetGroupList();
reqGetTempGroupList();
reqUnreadMsgGroupList();
}
private void reqGetGroupList() {
logger.i("group#reqGetGroupList");
SocketThread channel = IMLoginManager.instance().getMsgServerChannel();
if (channel == null) {
logger.e("contact#channel is null");
return;
}
channel.sendPacket(new GroupPacket(IMSession.SESSION_GROUP));
logger.i("group#send packet to server");
}
public void reqGetTempGroupList() {
logger.i("group#reqGetTempGroupList");
SocketThread channel = IMLoginManager.instance().getMsgServerChannel();
if (channel == null) {
logger.e("contact#channel is null");
return;
}
channel.sendPacket(new GroupPacket(IMSession.SESSION_TEMP_GROUP));
logger.i("group#send packet to server");
}
public boolean groupReadyConditionOk() {
return groupReady && tempGroupReady;
}
private boolean unreadMsgGroupListReadyConditionOk() {
return groupReadyConditionOk() && unreadMsgGroupListReady;
}
private void addGroup(GroupEntity group) {
logger.i("group#addGroup -> entity:%s", group);
PinYin.getPinYin(logger, group.name, group.pinyinElement);
groups.put(group.id, group);
}
public void onRepGroupList(DataBuffer buffer) {
logger.i("group#onRepGroupList");
GroupPacket packet = new GroupPacket();
packet.decode(buffer);
GroupPacket.PacketResponse resp = (GroupPacket.PacketResponse) packet.getResponse();
logger.i("group#group cnt:%d", resp.entityList.size());
for (GroupEntity group : resp.entityList) {
addGroup(group);
}
Header header = packet.getResponse().getHeader();
int commandId = header.getCommandId();
if (commandId == ProtocolConstant.CID_GROUP_DIALOG_LIST_RESPONSE) {
logger.d("group#tempgroup list is ready");
tempGroupReady = true;
} else if (commandId == ProtocolConstant.CID_GROUP_LIST_RESPONSE) {
logger.d("group#group list is ready");
groupReady = true;
}
if (groupReadyConditionOk()) {
ctx.sendBroadcast(new Intent(IMActions.ACTION_GROUP_READY));
logger.d("group#broadcast group ready msg");
IMUIHelper.triggerSearchDataReady(logger, ctx, IMContactManager.instance(), this);
}
triggerAddRecentInfo();
triggerReqUnreadMsgs();
}
private void triggerAddRecentInfo() {
if (groupReadyConditionOk()) {
for (Entry<String, GroupEntity> entry : groups.entrySet()) {
GroupEntity group = entry.getValue();
if (group == null) {
continue;
}
logger.d("group#recent#group:%s", group);
RecentInfo recentSession = IMContactHelper.convertGroupEntity2RecentInfo(group);
IMRecentSessionManager.instance().addRecentSession(recentSession);
}
IMRecentSessionManager.instance().broadcast();
}
}
public void changeTempGroupMembers(String groupId,
List<String> addingMemberList, List<String> removingMemberList) {
logger.d("changeTempGroupMembers gropuId:%s", groupId);
DumpUtils.dumpStringList(logger, "tempgroup#adding list", addingMemberList);
DumpUtils.dumpStringList(logger, "tempgroup#removing list", removingMemberList);
changeTempGroupMembersImpl(groupId, ADD_CHANGE_MEMBER_TYPE, addingMemberList);
changeTempGroupMembersImpl(groupId, REMOVE_CHANGE_MEMBER_TYPE, removingMemberList);
}
public void changeTempGroupMembersImpl(String groupId, int changeType,
List<String> memberList) {
logger.d("tempgroup#changeGroupMembers gropuId:%s, changeType:%d", groupId, changeType);
if (memberList.isEmpty()) {
logger.d("tempgroup#empty, no need to change");
return;
}
SocketThread channel = IMLoginManager.instance().getMsgServerChannel();
if (channel == null) {
logger.e("tempgroup#channel is null");
return;
}
ChangeTempGroupMemberPacket.PacketRequest.Entity param = new ChangeTempGroupMemberPacket.PacketRequest.Entity();
param.groupId = groupId;
param.changeType = changeType;
param.memberList = memberList;
channel.sendPacket(new ChangeTempGroupMemberPacket(param));
}
public void onRepChangeTempGroupMembers(DataBuffer buffer) {
logger.d("tempgroup#onRepchangeTempGroupMembers");
ChangeTempGroupMemberPacket packet = new ChangeTempGroupMemberPacket();
packet.decode(buffer);
ChangeTempGroupMemberPacket.PacketResponse resp = (ChangeTempGroupMemberPacket.PacketResponse) packet.getResponse();
ChangeTempGroupMemberPacket.PacketResponse.Entity entity = resp.entity;
logger.d("tempgroup#groupId:%s", entity.groupId);
boolean ok = handleChangeTempGroupMember(entity, entity.groupId);
logger.d("tempgroup#result ok:%s", ok);
Intent intent = new Intent(IMActions.ACTION_GROUP_CHANGE_TEMP_GROUP_MEMBER_RESULT);
intent.putExtra(SysConstant.OPERATION_RESULT_KEY, ok);
intent.putExtra(SysConstant.SESSION_ID_KEY, entity.groupId);
triggerAddRecentInfo();
ctx.sendBroadcast(intent);
}
private boolean handleChangeTempGroupMember(
ChangeTempGroupMemberPacket.PacketResponse.Entity entity,
String groupId) {
if (entity.result != 0) {
logger.e("tempgroup#onRepChangeTempGroupMembers failed, result:%d", entity.result);
return false;
}
GroupEntity group = findGroup(groupId);
if (group == null) {
logger.e("tempgroup#no such group:%s", groupId);
return false;
}
if (entity.memberList == null || entity.memberList.isEmpty()) {
logger.e("tempgroup#memberList are empty");
return false;
}
DumpUtils.dumpStringList(logger, getChangeMemberTypeString(entity.changeType), entity.memberList);
if (entity.changeType == ADD_CHANGE_MEMBER_TYPE) {
group.memberIdList.addAll(entity.memberList);
} else if (entity.changeType == REMOVE_CHANGE_MEMBER_TYPE) {
group.memberIdList.removeAll(entity.memberList);
}
return true;
}
public void reqCreateTempGroup(String tempGroupName, List<String> memberList) {
logger.d("tempgroup#reqCreateTempGroup, name:%s, member cnt:%d", tempGroupName, memberList.size());
SocketThread channel = IMLoginManager.instance().getMsgServerChannel();
if (channel == null) {
logger.e("tempgroup#channel is null");
return;
}
String dummyTempGroupAvatarUrl = "";
channel.sendPacket(new CreateTempGroupPacket(tempGroupName, dummyTempGroupAvatarUrl, memberList));
logger.i("tempgroup#send packet to server");
}
public void onRepCreateTempGroup(DataBuffer buffer) {
logger.d("tempgroup#onRepCreateTempGroup");
CreateTempGroupPacket packet = new CreateTempGroupPacket();
packet.decode(buffer);
CreateTempGroupPacket.PacketResponse resp = (CreateTempGroupPacket.PacketResponse) packet.getResponse();
Intent intent = new Intent(IMActions.ACTION_GROUP_CREATE_TEMP_GROUP_RESULT);
intent.putExtra(SysConstant.OPERATION_RESULT_KEY, resp.result);
if (resp.result != 0) {
logger.e("tempgroup#createTempGroup failed");
} else {
GroupEntity group = resp.entity;
addGroup(group);
intent.putExtra(SysConstant.SESSION_ID_KEY, group.id);
triggerAddRecentInfo();
// todo eric, the return value has bug, updated time is not right,
// and the member cnt is also not right
// reqGetTempGroupList();
}
ctx.sendBroadcast(intent);
}
private void reqUnreadMsgGroupList() {
logger.i("unread#reqUnreadMsgGroupList");
SocketThread channel = IMLoginManager.instance().getMsgServerChannel();
if (channel == null) {
logger.e("unread#channel is null");
return;
}
channel.sendPacket(new UnreadMsgGroupListPacket());
logger.i("unread#send packet to server");
}
public void onRepUnreadMsgGroupList(DataBuffer buffer) {
logger.i("unread#onRepUnreadMsgGroupList");
UnreadMsgGroupListPacket packet = new UnreadMsgGroupListPacket();
packet.decode(buffer);
UnreadMsgGroupListPacket.PacketResponse resp = (UnreadMsgGroupListPacket.PacketResponse) packet.getResponse();
logger.i("unread#unreadMsgGroupList cnt:%d", resp.entityList.size());
unreadMsgGroupList = resp.entityList;
unreadMsgGroupListReady = true;
triggerReqUnreadMsgs();
}
private void triggerReqUnreadMsgs() {
logger.d("unread#group triggerReqUnreadMsgs");
if (unreadMsgGroupListReadyConditionOk()) {
reqUnreadMgs();
} else {
logger.d("unread#condition is not ok");
}
}
private void reqUnreadMgs() {
logger.i("unread#group reqUnreadMsgs");
SocketThread channel = IMLoginManager.instance().getMsgServerChannel();
if (channel == null) {
logger.e("unread#channel is null");
return;
}
for (UnreadMsgGroupListPacket.PacketResponse.Entity entity : unreadMsgGroupList) {
logger.d("unread#sending unreadmsg request -> groupId:%s", entity.groupId);
GroupUnreadMsgPacket.PacketRequest.Entity requestParam = new GroupUnreadMsgPacket.PacketRequest.Entity();
requestParam.groupId = entity.groupId;
channel.sendPacket(new GroupUnreadMsgPacket(requestParam));
logger.i("unread#send packet to server");
}
}
}