package com.pingpang.websocketchat.send.impl;

import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.pingpang.util.StringUtil;
import com.pingpang.websocketchat.ChatType;
import com.pingpang.websocketchat.Message;
import com.pingpang.websocketchat.send.ChatSend;

import io.netty.channel.ChannelHandlerContext;

public class ChatSendUtil {
	private static Logger logger=LoggerFactory.getLogger(ChatSendUtil.class);
	//执行类存储
	private static Map<String,ChatSend> currentChat=new ConcurrentHashMap<String,ChatSend>();
	
	private static ThreadPoolExecutor pool=new ThreadPoolExecutor(2, Runtime.getRuntime().availableProcessors()*2, 10, TimeUnit.SECONDS, new ArrayBlockingQueue(10),new RejectedExecutionHandler() {
		@Override
		public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
			logger.info("线程{}丢弃了",r);
		}
	});
	
	//初始化操作
	private static void init() {
		//绑定操作
		currentChat.put(ChatType.BIND, new ChatSendBind());
		
		//离线操作
		currentChat.put(ChatType.LEAVE, new ChatSendLeave());
		
		//单聊
		currentChat.put(ChatType.SINGLE, new ChatSendSingle());
		
		//群聊
		currentChat.put(ChatType.GROUP, new ChatSendGroup());
		
		//查询用户在线用户
		currentChat.put(ChatType.QUERY_USER, new ChatSendQueryUser());
		
		//查询群组信息的
		currentChat.put(ChatType.QUERY_GROUP, new ChatSendQueryGroup());
		
		//进群
	    currentChat.put(ChatType.ADD_GROUP, new ChatSendAddGroup());
				
		//离群
	    currentChat.put(ChatType.REMORE_GROUP, new ChatSendRemoreGroup());
	    
	    //获取离离线消息
	    currentChat.put(ChatType.QUERY_OLD_MSG, new ChatSendGetOldMsg());
	    
	    //获取最近聊天用户
	    currentChat.put(ChatType.QUERY_OLD_USER, new ChatSendQueryOldUser());
	    
	     //通知聊天 接收11 request refuse accept
	    currentChat.put(ChatType.AUDIO_QUERY, new ChatSendAudio());
	    
	    //直播信息 12
	    currentChat.put(ChatType.AUDIO_LIVE, new ChatSendAudioLive());
	    
	    //图片特效13
	    currentChat.put(ChatType.AUDIO_MAGIC, new ChatSendAudioMagic());
	    
	    //实时语音14
	    currentChat.put(ChatType.VOICE, new ChatSendVoice());
	}
	
	private static ChatSend getChatChatSend(String cmd) {
		switch (cmd) {
		     case  ChatType.BIND:
		    	   return new ChatSendBind();
		     case  ChatType.LEAVE:
		    	   return new ChatSendLeave();
		     case  ChatType.SINGLE:
		    	   return new ChatSendSingle();
		     case  ChatType.GROUP:
		    	   return new ChatSendGroup();
		     case  ChatType.QUERY_USER:
		    	   return new ChatSendQueryUser();
		     case  ChatType.QUERY_GROUP:
		    	   return new ChatSendQueryGroup();
		     case  ChatType.ADD_GROUP:
		    	   return new ChatSendAddGroup();
		     case  ChatType.REMORE_GROUP:
		    	   return new ChatSendRemoreGroup();
		     case  ChatType.QUERY_OLD_MSG:
		    	   return new ChatSendGetOldMsg();
		     case  ChatType.QUERY_OLD_USER:
		    	   return new ChatSendQueryOldUser();
		     case  ChatType.AUDIO_QUERY:
		    	   return new ChatSendAudio();
		     case  ChatType.AUDIO_LIVE:
		    	   return new ChatSendAudioLive();
		     case  ChatType.AUDIO_MAGIC:
		    	   return new ChatSendAudioMagic();
		     case  ChatType.VOICE:
		    	   return new ChatSendVoice();
		    default:
		    	   return null;
		}
	}
	
	/**
	   *  获取执行类 
	 * @param msg
	 * @param ctx
	 * @throws Exception 
	 */
	public static void getChatSend(String msg, ChannelHandlerContext ctx) throws Exception {
		
		if(StringUtil.isNUll(msg)) {
			return;
		}
		
		if(currentChat.isEmpty()) {
			init();
		}
		
		ObjectMapper mapper = new ObjectMapper();
		Message message = mapper.readValue(msg, Message.class);
		
		if(null!=message &&
		   !StringUtil.isNUll(message.getCmd()) && 
		   null!=currentChat.get(message.getCmd())) {
//		   currentChat.get(message.getCmd()).isSend(message, ctx);
			//这里改为多线程处理了
//			Map<String,Object> msgMap=new ConcurrentHashMap<String, Object>();
//			msgMap.put("message", message);
//			msgMap.put("ctx", ctx);
//			ChatSend ch=getChatChatSend(message.getCmd());
//			ch.threadLocal.set(msgMap);
//			//ch.threadLocal.get();
//			new Thread(ch).start();
			ChatSend ch=getChatChatSend(message.getCmd());
			ch.setChatSend(message, ctx);
			pool.execute(ch);
		}
	}
	
	/**
	  * 应用于集群消息推送
	 * @param message
	 * @throws Exception 
	 */
	public static void getChatSend(Message message) throws Exception {
		
		if(currentChat.isEmpty()) {
			init();
		}
		
		if(null!=message &&
				   !StringUtil.isNUll(message.getCmd()) && 
				   null!=currentChat.get(message.getCmd())) {
				   currentChat.get(message.getCmd()).isSend(message, null);
		}
	} 
}
