package cc.ly.mc.core.context;

import cc.ly.mc.core.attribute.Attributes;
import cc.ly.mc.core.data.impl.Integer32;
import cc.ly.mc.core.message.Message;
import cc.ly.mc.core.message.RelayMessage;
import io.netty.channel.ChannelId;

import java.util.concurrent.ConcurrentHashMap;

import cc.ly.mc.core.data.impl.Integer64;
import cc.ly.mc.core.data.impl.Unsigned16;

public enum IdentityContext {

	INSTANCE;

	private final ConcurrentHashMap<Integer, Identity> IDENTITIES = new ConcurrentHashMap<>();

	private final ConcurrentHashMap<ChannelId, Integer> CHANNEL_ID_TO_ID = new ConcurrentHashMap<>();

	IdentityContext() {
	}

	public void forward(Message message) {
		Integer to = ((Integer32) message.attribute(Attributes.RECEIVER_ID.getCode()).data()) .get();
		Identity identity = get(to);
		if(identity != null){
			identity.write(message);
		}
	}

	public void add(Identity identity) {
		Identity old = IDENTITIES.put(identity.id(), identity);
		if(old != null){
			old.context().close();
		}
		CHANNEL_ID_TO_ID.put(identity.context().channel().id(), identity.id());
	}

	public void remove(Integer id) {
		if (id != null) {
			IDENTITIES.remove(id);
		}
	}

	public void remove(ChannelId channelId) {
		remove(CHANNEL_ID_TO_ID.remove(channelId));
	}
	
	public Identity get(ChannelId channelId){
		Integer id = CHANNEL_ID_TO_ID.get(channelId);
		return IDENTITIES.get(id);
	}

	public Identity get(Integer id) {
		return IDENTITIES.get(id);
	}

	public Identity getServer(){
		return IDENTITIES.get(Identity.SERVER_ID);
	}

}

@@ -152,51 +152,8 @@
 ge;%0A
-import cc.ly.mc.core.message.RelayMessage;%0A
 impo
@@ -205,122 +205,92 @@
 til.
-concurrent.ConcurrentHashMap;%0A%0Aimport cc.ly.mc.core.data.impl.Integer64;%0Aimport cc.ly.mc.core.data.impl.Unsigned16
+Iterator;%0Aimport java.util.LinkedList;%0Aimport java.util.concurrent.ConcurrentHashMap
 ;%0A%0Ap
@@ -524,16 +524,124 @@
 p%3C%3E();%0A%0A
+%09private final ConcurrentHashMap%3CInteger, LinkedList%3CMessage%3E%3E DELAY_MESSAGES = new ConcurrentHashMap%3C%3E();%0A%0A
 %09Identit
@@ -876,16 +876,201 @@
 ssage);%0A
+%09%09%7Delse%7B%0A%09%09%09synchronized (this) %7B%0A%09%09%09%09if (!DELAY_MESSAGES.containsKey(to)) %7B%0A%09%09%09%09%09DELAY_MESSAGES.put(to, new LinkedList%3CMessage%3E());%0A%09%09%09%09%7D%0A%09%09%09%09DELAY_MESSAGES.get(to).add(message);%0A%09%09%09%7D%0A
 %09%09%7D%0A%09%7D%0A%0A
@@ -1288,16 +1288,346 @@
 .id());%0A
+%09%09synchronized (this)%7B%0A%09%09%09if(DELAY_MESSAGES.containsKey(identity.id()) && DELAY_MESSAGES.get(identity.id()).size() %3E 0)%7B%0A%09%09%09%09LinkedList%3CMessage%3E messages = DELAY_MESSAGES.get(identity.id());%0A%09%09%09%09Iterator%3CMessage%3E it = messages.iterator();%0A%09%09%09%09while (it.hasNext())%7B%0A%09%09%09%09%09identity.write(it.next());%0A%09%09%09%09%09it.remove();%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A
 %09%7D%0A%0A%09pub

处理当对方不在线的时候，保留消息，当对方上线是发送消息到对方