package org.framework.lazy.cloud.network.heartbeat.client.netty.udp.handler;


import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.framework.lazy.cloud.network.heartbeat.common.constant.UdpMessageType;
import org.framework.lazy.cloud.network.heartbeat.common.NettyProxyMsg;
import org.framework.lazy.cloud.network.heartbeat.common.adapter.ChannelTypeAdapter;
import org.framework.lazy.cloud.network.heartbeat.common.utils.ChannelAttributeKeyUtils;

/**
 * 客户端访客通信通道 处理器
 */
@Slf4j
public class NettyUdpClientPermeateClientTransferHandler extends SimpleChannelInboundHandler<NettyProxyMsg> {
    private final ChannelTypeAdapter channelTypeAdapter;

    public NettyUdpClientPermeateClientTransferHandler(ChannelTypeAdapter channelTypeAdapter) {
        this.channelTypeAdapter = channelTypeAdapter;
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
    }

    @Override
    public void channelRead0(ChannelHandlerContext ctx, NettyProxyMsg nettyProxyMsg) throws Exception {
        Channel channel = ctx.channel();
        channelTypeAdapter.handler(channel, nettyProxyMsg);

    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {

        String clientId = ChannelAttributeKeyUtils.getClientId(ctx.channel());
        String visitorId = ChannelAttributeKeyUtils.getVisitorId(ctx.channel());
        // 关闭访客
        Channel nextChannel = ChannelAttributeKeyUtils.getNextChannel(ctx.channel());
        if (nextChannel != null) {
            // 上报关闭这个客户端的访客通道
            NettyProxyMsg closeVisitorMsg = new NettyProxyMsg();
            closeVisitorMsg.setType(UdpMessageType.UDP_REPORT_CLIENT_PERMEATE_CLIENT_TRANSFER_CLOSE);
            closeVisitorMsg.setVisitorId(visitorId);
            nextChannel.writeAndFlush(closeVisitorMsg);
        }

        super.channelInactive(ctx);
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        if (ctx.channel().isWritable()) {
            log.debug("Channel is writable again");
            // 恢复之前暂停的操作，如写入数据
        } else {
            log.debug("Channel is not writable");
            // 暂停写入操作，等待可写状态
        }
        log.info("channelWritabilityChanged!");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }
}