package org.ts.ddcs.net;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.ReferenceCountUtil;
import org.ts.ddcs.dataStream.TcpDataStreamAdapter;
import org.ts.ddcs.log.LogHelper;

import java.net.SocketAddress;

/**
 * TCP网络通道处理器
 *
 * @author dylan
 */
public class DataDiscardHandler extends ChannelInboundHandlerAdapter {

    private String channelKey;
    private String bindAgreeement;
    private TcpDataStreamAdapter templateAdapter = new TcpDataStreamAdapter();


    public DataDiscardHandler(String channelKey, String bindAgreeement) {
        this.channelKey = channelKey;
        this.bindAgreeement = bindAgreeement;
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        try {
            LogHelper.info("channel handler " + this.templateAdapter.getAdapterKey() + " handlerAdded " + ctx.name());
            SocketAddress socketAddress = ctx.channel().remoteAddress();
            String remoteIp = "";
            if (null != socketAddress) {
                remoteIp = socketAddress.toString();
                int index = remoteIp.lastIndexOf("/");
                if (index >= 0) {
                    remoteIp = remoteIp.substring(index + 1);
                }
            }
            this.templateAdapter.init(remoteIp);
            // DataChannelHolder.newInstance().dataChannel.online(this.templateAdapter);
        } catch (Exception e) {
            LogHelper.error(e);
            ctx.close();
        }
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf) msg;
        try {
            LogHelper.info("channel handler " + this.templateAdapter.getAdapterKey() + " channelRead");
            this.templateAdapter.pushData(in, ctx);
        } catch (Exception e) {
            LogHelper.error(e);
        } finally {
            ReferenceCountUtil.release(in);
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        try {
            LogHelper.info("channel handler " + this.templateAdapter.getAdapterKey() + " exceptionCaught " + cause.getMessage());
            this.templateAdapter.close();
            //DataChannelHolder.newInstance().dataChannel.offline(this.templateAdapter);
        } catch (Exception e) {
            LogHelper.error(e);
        } finally {
            ctx.close();
            LogHelper.error(cause.getMessage());
        }
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        try {
            LogHelper.info("channel handler " + this.templateAdapter.getAdapterKey() + " handlerRemoved");
            this.templateAdapter.close();
            // DataChannelHolder.newInstance().dataChannel.offline(this.templateAdapter);
        } catch (Exception e) {
            LogHelper.error(e);
        }
    }
}
