package cn.bunny.service.netty.demo5;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.Charset;

@Slf4j
public class PipLineServerOutbound {
    public static void main(String[] args) {
        new ServerBootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
                        // 通过 Channel 拿到pipLine
                        ChannelPipeline pipeline = nioSocketChannel.pipeline();
                        // handler 处理结果
                        pipeline.addLast("h1", new ChannelInboundHandlerAdapter() {
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                log.info("第一个");
                                ByteBuf buf = (ByteBuf) msg;
                                String name = buf.toString(Charset.defaultCharset());
                                super.channelRead(ctx, name);
                            }
                        });

                        // handler 第二个处理结果
                        pipeline.addLast("h2", new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                log.info("第二个");
                                // 将数据传输给下一个链，如果不使用下一个不会接受到相应内容
                                super.channelRead(ctx, msg);
                            }
                        });


                        // 第四个出栈内容
                        pipeline.addLast("h4", new ChannelOutboundHandlerAdapter() {
                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                log.info("第四个 出栈");
                                super.write(ctx, msg, promise);
                            }
                        });

                        // handler 第三个处理结果
                        pipeline.addLast("h3", new ChannelInboundHandlerAdapter() {
                            @Override
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                log.info("第三个 是否拿到上一个参数：{}", msg);
                                ctx.writeAndFlush(ctx.alloc().buffer().writeBytes("服务。。。".getBytes()));
                            }
                        });

                        // 第五个出栈内容
                        pipeline.addLast("h5", new ChannelOutboundHandlerAdapter() {
                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                log.info("第五个 出栈");
                                super.write(ctx, msg, promise);
                            }
                        });

                        // 第六个出栈内容
                        pipeline.addLast("h6", new ChannelOutboundHandlerAdapter() {
                            @Override
                            public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
                                log.info("第六个 出栈");
                                super.write(ctx, msg, promise);
                            }
                        });
                    }
                }).bind(8080);

        // 进栈：按照顺序进行
        // 出栈：从后往前走
        /**
         *  ctx.writeAndFlush(ctx.alloc().buffer().writeBytes("服务。。。".getBytes())); 出栈
         *  顺序和正常不一样，从当前调用的往前找，所以这个顺序是1234，因为4在3前面，当三执行完成后，4是出栈，所以之后才会执行4
         */
    }
}
