package com.yonge.netty.server.handler;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.stereotype.Component;

@Component
@ChannelHandler.Sharable
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

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

	@Autowired
	private NettyChannelManager channelManager;

	@Override
	public void channelActive(ChannelHandlerContext ctx) {
		// 从管理器中添加
		channelManager.add(ctx.channel());
	}

	@Override
	public void channelUnregistered(ChannelHandlerContext ctx) {
		// 从管理器中移除
		channelManager.remove(ctx.channel());
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
		LOGGER.error("[exceptionCaught][连接({}) 发生异常]", ctx.channel().id(), cause);
		// 断开连接
		ctx.channel().close();
	}

	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
		if (evt instanceof WebSocketServerProtocolHandler.HandshakeComplete) {
			WebSocketServerProtocolHandler.HandshakeComplete handshakeComplete = (WebSocketServerProtocolHandler.HandshakeComplete) evt;
			String requestUri = handshakeComplete.requestUri();
			
			String userId = StringUtils.substringAfterLast(requestUri, "?");
			
			if(StringUtils.isBlank(userId) || !StringUtils.isNumeric(userId)){
				userId = StringUtils.substringAfterLast(requestUri, "/");
			}
			
			Channel channel = ctx.channel();
			
			if(!StringUtils.isNumeric(userId)){
				// 断开连接
				channel.close();
			}
			
			channelManager.addUser(channel, userId);
			
			LOGGER.info("userId:[{}]", userId);
			
			HttpHeaders httpHeaders = handshakeComplete.requestHeaders();
			String authHeader = httpHeaders.get("Authorization");
			
			String tokenValue = authHeader.toLowerCase().replace(OAuth2AccessToken.BEARER_TYPE.toLowerCase(), StringUtils.EMPTY).trim();
			LOGGER.info("token:[{}]", tokenValue);
		}
		super.userEventTriggered(ctx, evt);
	}

}
