package com.docus.server.common.netty.client;

import com.docus.server.common.JsonDecoder;
import com.docus.server.common.JsonEncoder;
import com.docus.server.common.netty.client.handler.ClientHandler;
import com.docus.server.common.netty.client.handler.HeartbeatHandler;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.timeout.IdleStateHandler;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;


@AllArgsConstructor
@NoArgsConstructor
public class NettyClientInitializer extends ChannelInitializer<Channel> {

    private NettyClientProperties nettyProperties;

    private NettyClient nettyClient;

    private String appName;

    @Override
    protected void initChannel(Channel channel) throws Exception {
        channel.pipeline()
            // 加载空闲监听器
            .addLast(new IdleStateHandler(nettyProperties.getReaderIdleTimeSeconds(),
                nettyProperties.getWriterIdleTimeSeconds(), nettyProperties.getAllIdleTimeSeconds()))
            // 加载加码解码处理器，同时解决粘包拆包问题
//            .addLast(new ProtobufVarint32FrameDecoder())
//            .addLast(new ProtobufDecoder(Payload.Message.getDefaultInstance()))
//            .addLast(new ProtobufVarint32LengthFieldPrepender())
//            .addLast(new ProtobufEncoder())
//            .addLast(new LineBasedFrameDecoder(2048))
//            .addLast(new LineBasedFrameDecoder(1024))
//            .addLast(new StringDecoder(CharsetUtil.UTF_8))
            .addLast(new LengthFieldBasedFrameDecoder(1024 * 1024, 0, 2, 0, 2))
            // LengthFieldPrepender是一个编码器，主要是在响应字节数据前面添加字节长度字段
            .addLast(new LengthFieldPrepender(2))
            // 对经过粘包和拆包处理之后的数据进行json反序列化，从而得到UserInfo对象
            .addLast(new JsonDecoder())
            // 对响应数据进行编码，主要是将UserInfo对象序列化为json
            .addLast(new JsonEncoder())
            // 加载心跳处理器
            .addLast(new HeartbeatHandler(nettyClient, nettyProperties, appName))
            // 加载业务处理器
            .addLast(new ClientHandler(nettyClient))
            .addLast();
    }


}
