package com.pingpang.websocketchat;

import java.util.Date;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.pingpang.redis.RedisPre;
import com.pingpang.redis.service.RedisService;
import com.pingpang.service.UserService;
import com.pingpang.util.StringUtil;

import io.netty.channel.Channel;
 
@Component
public class ChannelManager {

	// 用户信息处理
    private static UserService userService;

    // redis操作
 	private static RedisService redisService;
	
 	public  UserService getUserService() {
		return userService;
	}

 	@DubboReference
	public  void setUserService(UserService userService) {
		ChannelManager.userService = userService;
	}


	public static RedisService getRedisService() {
		return redisService;
	}

	@DubboReference
	public  void setRedisService(RedisService redisService) {
		ChannelManager.redisService = redisService;
	}


	/*
	 * 用户  
	 */
	private static Map<ChartUser, Channel> userChannel = new ConcurrentHashMap <ChartUser, Channel>();

	
	//日志操作
    private static Logger logger = LoggerFactory.getLogger(ChannelManager.class);
	
	/**
	 * 通过用户代码获取用户信息
	 * @param userCode
	 * @return
	 */
	public static ChartUser getChartUser(String userCode) {
		if(!StringUtil.isNUll(userCode)) {
			 ChartUser cu=new ChartUser();
			 cu.setUserCode(userCode);
			 return userService.getUser(cu);
		}else {
		     return null;
		}
	}
	
	
	/**
	 * 通过用户代码获取用户信息
	 * @param userCode
	 * @return
	 */
	public static ChartUser getChartOnUser(String userCode) {
		if(!StringUtil.isNUll(userCode)) {
			 return userService.getUserMap(userCode);
		}else {
		     return null;
		}
	}
	
	/**
	 * 通过channel获取用户信息
	 * 判断是否是当前的用户操作
	 */
	public static ChartUser getChatUseByChannel(Channel ctx) {
		for(Map.Entry<ChartUser, Channel> map : userChannel.entrySet()) {
			if(map.getValue().equals(ctx)) {
				return map.getKey();
			}
		}
		return new ChartUser();
	}
	
	
	/**
	   * 判断当前用户是否绑定了Channel
	 * @param cu
	 * @return
	 */
	public static boolean isExitChannel(ChartUser cu) {
		if(null==cu) {
			return false;
		}
		return userChannel.containsKey(cu);
	}
	
	/*
	 * 添加用户
	 */
	public static void addChannel(ChartUser chartUser, Channel ch) {
		logger.info("添加用户:" + chartUser.getUserCode()+chartUser.getUserName()+ "IP:" + ch.remoteAddress());
		userChannel.put(chartUser, ch);
	}

	/*
	 * 获取用户
	 */
	public static Channel getChannel(String userCode) {
       	
		//用户下线了
		if(null==ChannelManager.getChartUser(userCode)) {
			return null;
		} 
		
		return ChannelManager.userChannel.get(ChannelManager.getChartUser(userCode));
	}

	/*
	 * 移除用户
	 */
	public static void removeChannelByCode(String userCode) {
		logger.info("移除用户:" + userCode);
		if(StringUtil.isNUll(userCode) || null==getChartUser(userCode)) {
			return;
		}
		
		ChartUser cu=getChartUser(userCode);
		//删除对象
		userChannel.remove(cu);
		//移除群组
		removeGroup(userCode);
		//删除服务端绑定信息
		redisService.removeSet(RedisPre.NETTY_USER_SET, cu);
	    //redisService.delGroupUser(RedisPre.NETTY_USER_SET, "userCode", cu.getUserCode());
		//删除绑定数据
	    redisService.delete(RedisPre.DB_USER+cu.getUserCode());
		//userService.dbDownUser(userCode, "0");
	}

	/*
	 * 移除用户
	 */
	public static void removeChannelByChannel(Channel channel) {
		for (ChartUser key : userChannel.keySet()) {
			if (userChannel.get(key).equals(channel)) {
				logger.info("移除用户:" + key + "IP:" + channel.remoteAddress());
				removeChannelByCode(key.getUserCode());
				//removeGroup(key.getUserCode());
				return;
			}
		}
	}

	//获取所有用户信息
	public static Set<ChartUser> getAllUser(){
		Set<ChartUser> allNettyUser=(Set<ChartUser>)(Set<?>)redisService.getSet(RedisPre.NETTY_USER_SET);
		//return userChannel.keySet();
		return allNettyUser;
	}
	
	/*
	 * 添加群组
	 */
	public static void addGroup(ChatGroup groupID, ChartUser cu) {
		
         if(null==groupID || null==cu ||StringUtil.isNUll(groupID.getGroupCode()) || StringUtil.isNUll(cu.getUserCode())) {
        	 return;
         }	
         redisService.addSet(RedisPre.DB_GROUP_SET+groupID.getGroupCode(), cu);
	}

	/**
	 * 移除群组
	 * @param groupID
	 * @param userCode
	 */
	public static void removeGroup(ChatGroup groupID,String userCode) {
		if(null==groupID ||StringUtil.isNUll(groupID.getGroupCode()) || StringUtil.isNUll(userCode)) {
       	 return;
        }	
		redisService.removeSet(RedisPre.DB_GROUP_SET+groupID.getGroupCode(),getChartUser(userCode));
	}
	
	/**
	 * 移除群组
	 * @param userCode
	 */
	public static void removeGroup(String userCode) {
		if(StringUtil.isNUll(userCode)) {
			return;
		}
		
		Set<String> groupSet=redisService.getSetPrex(RedisPre.DB_GROUP_SET+"*");
		if(null==groupSet || groupSet.isEmpty()) {
			return;
		}
		
		//ChartUser cu=getChartUser(userCode);
		for(String str:groupSet) {
			//删除群组里面的信息
		   //redisService.delGroupUser(str, "userCode", userCode);
			redisService.removeSet(str, getChartUser(userCode));
		}
	}
	
	/**
	 * 查找是否存在
	 * @param groupID
	 * @param userCode
	 * @return
	 */
	public static boolean isExit(ChatGroup groupID,String userCode) {
		return redisService.contains(RedisPre.DB_GROUP_SET+groupID.getGroupCode(), getChartUser(userCode));
		//return redisService.contains(RedisPre.DB_GROUP_SET+groupID.getGroupCode(),"userCode", userCode);
	}
	
	/**
	 * 获取群组用户
	 * @param groupID
	 * @return
	 */
	public static Set<ChartUser> getGroupUser(ChatGroup groupID){
		if(null==groupID) {
			return new HashSet<ChartUser>();
		}
		return (Set<ChartUser>)(Set<?>)redisService.getSet(RedisPre.DB_GROUP_SET+groupID.getGroupCode());
	}
	
	
	/**
	 * 广播消息
	 * @param userCode
	 */
	public static void sendAlertMsgByCode(String userCode,String msg) {
		logger.info("广播用户:" + userCode);
		if(StringUtil.isNUll(userCode) || null==getChartUser(userCode)) {
			return;
		}
		
		Message message=new Message();
		message.setMsg(msg);
		ChartUser admin=new ChartUser();
		admin.setUserCode("admin");
		admin.setUserName("管理员");
		message.setFrom(admin);
		message.setCmd("2");
		
		ChartUser cu=new ChartUser();
		cu.setUserCode(userCode);
		message.setAccept(userService.getUser(cu));
		
		message.setCreateDate(StringUtil.format(new Date()));
		
		redisService.SendMsg(message);
	}
	
	
	public static void main(String[] args) {
		ChartUser cu1=new ChartUser();
		cu1.setUserCode("001");
		
		ChartUser cu2=new ChartUser();
		cu2.setUserCode("001");
		
		ChartUser cu3=new ChartUser();
		cu3.setUserCode("001");
		
		ChatGroup cg=new ChatGroup();
		cg.setGroupCode("G001");
		ChannelManager.addGroup(cg, cu1);
		ChannelManager.addGroup(cg, cu2);
		ChannelManager.addGroup(cg, cu3);
		
		System.out.println(ChannelManager.getGroupUser(cg).size());
	}
}
