package org.jeecg.modules.nettyServer.handler;

import io.netty.channel.Channel;
import org.jeecg.modules.nettyServer.store.ChannelStore;
import org.jeecg.modules.nettyServer.store.WebSocketSession;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.modules.nettyServer.store.WellChannelStore;
import org.springframework.stereotype.Component;


/**
 * 消息处理,单例启动
 *
 * @author cn2008tv
 */
@Slf4j
@Component
@ChannelHandler.Sharable
@RequiredArgsConstructor
public class MessageHandler extends SimpleChannelInboundHandler<WebSocketFrame> {

    private final WebsocketMessageHandler websocketHandler;

    /**
     * 每当服务端收到新的客户端连接时,客户端的channel存入ChannelGroup列表中,并通知列表中其他客户端channel
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        // 获取连接的channel
//        Channel incomming = ctx.channel();
        //通知所有已经连接到服务器的客户端，有一个新的通道加入
        /*for(Channel channel:channelGroup){
            channel.writeAndFlush("[SERVER]-"+incomming.remoteAddress()+"加入\n");
        }*/
//        ChannelStore.bind(ctx,ctx.channel().id().toString());
        log.info("添加新的channel, incomming: {}",ctx.channel().id());
    }

    /**
     * 每当服务端断开客户端连接时,客户端的channel从ChannelGroup中移除,并通知列表中其他客户端channel
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        //获取连接的channel
        /*Channel incomming = ctx.channel();
        for(Channel channel:channelGroup){
            channel.writeAndFlush("[SERVER]-"+incomming.remoteAddress()+"离开\n");
        }*/
        //从服务端的channelGroup中移除当前离开的客户端
        WellChannelStore.closeAndClean(ctx);
        WebSocketSession.clear(ctx.channel().id());
//        channelGroup.remove(ctx.channel());
//
//        //从服务端的channelMap中移除当前离开的客户端
//        Collection<Channel> col = channelMap.values();
//        while (true == col.contains(ctx.channel())) {
//            col.remove(ctx.channel());
//            log.info("netty客户端连接删除成功!");
//        }

    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof FullHttpRequest) {
            websocketHandler.handleHttpRequest(ctx, (FullHttpRequest) msg);
            log.debug("\n");
            log.debug("客户端{}握手成功!", ctx.channel().id());
        }
        super.channelRead(ctx, msg);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception {
        log.debug("\n");
        log.info("channelId:" + ctx.channel().id());
        websocketHandler.handleWebSocketFrame(ctx, frame);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        log.debug("\n");
        log.debug("断开连接");
        // 释放缓存
        WellChannelStore.closeAndClean(ctx);
        WebSocketSession.clear(ctx.channel().id());
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.debug("\n");
        log.debug("成功建立连接,channelId：{}", ctx.channel().id());
        super.channelActive(ctx);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        log.debug("心跳事件时触发");
    }

    /**
     * 当服务端的IO 抛出异常时被调用
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        Channel incoming = ctx.channel();
        log.error("SimpleChatClient:" + incoming.remoteAddress() + "异常", cause);
        //异常出现就关闭连接
        ctx.close();
    }
}
