package com.yonge.netty.server.handler.message;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSONPath;
import com.yonge.netty.server.handler.ChannelContextConstants;
import com.yonge.netty.server.handler.NettyChannelManager;

@Component
@ChannelHandler.Sharable
public class TextWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> implements ApplicationContextAware,InitializingBean {

	private static final Logger LOGGER = LoggerFactory.getLogger(TextWebSocketHandler.class);

	@Autowired
	private NettyChannelManager nettyChannelManager;
	
	private ApplicationContext applicationContext;
	
	private Map<String, MessageHandler> handlerMap;

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) throws Exception {

		Channel channel = ctx.channel();

		String jsonMsg = frame.text();
		
		LOGGER.info("接收到客户端的消息内容：{}", jsonMsg);
		
		String action = (String) JSONPath.extract(jsonMsg, "$.header.type");
		
		if(StringUtils.isNoneBlank(action)){
			channel.attr(ChannelContextConstants.CHANNEL_ATTR_KEY_ACTION).set(action);
			
			if(handlerMap == null){
				LOGGER.error("消息处理器没有初始化");
			}
			MessageHandler handler = handlerMap.get(action);
			
			if(handler != null){
				handler.handleTextMessage(nettyChannelManager.getUser(channel), channel, jsonMsg);
			}
		}
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		handlerMap = applicationContext.getBeansOfType(MessageHandler.class).values().stream()
				.collect(Collectors.toMap(MessageHandler::getAction, t -> t));
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		this.applicationContext = applicationContext;
	}

}
