package org.ts.ddcs.dataStream;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.socket.DatagramPacket;
import lombok.extern.slf4j.Slf4j;

import java.net.InetSocketAddress;


/**
 * created by swp on 2017/8/21
 * 适配器，用于匹配数据模板与数据处理器
 *
 * @author dylan
 */
@Slf4j
public class UdpDataStreamAdapter extends DataStreamAdapter {

    private InetSocketAddress socketAddress = null;

    public UdpDataStreamAdapter() {
        super();
    }

    @Override
    public void output(byte[] respBody) {
        if (null != ctx) {
            try {
                ByteBuf buf = Unpooled.buffer(respBody.length);
                buf.writeBytes(respBody);
                if (null != socketAddress) {
                    DatagramPacket datagram = new DatagramPacket(buf, socketAddress);
                    ChannelFuture cf = this.ctx.writeAndFlush(datagram);
                    cf.addListener(new ChannelFutureListener() {
                        @Override
                        public void operationComplete(ChannelFuture channelFuture) throws Exception {
                            //写操作完成，并没有错误发生
                            if (channelFuture.isSuccess()) {
                                log.info("{} udp writeAndFlush is successful!!", adapterKey);
                            } else {
                                //记录错误
                                log.info("{} udp writeAndFlush is error {}", adapterKey, channelFuture.cause().getMessage());
                            }
                        }
                    });
                }
            } catch (Exception e) {
                log.error(adapterKey, e);
            } finally {
                log.info("{} udp output to rtuCode:{} ip:{} port:{}", adapterKey, rtuCode, socketAddress.getHostName(), socketAddress.getPort());
            }
        } else {
            log.info("{} udp ctx is null", adapterKey);
        }
    }

    @Override
    public void pushData(ByteBuf buf, ChannelHandlerContext cx, DatagramPacket datagramPacket) {
        try {
            this.ctx = cx;
            this.socketAddress = new InetSocketAddress(datagramPacket.sender().getAddress(), datagramPacket.sender().getPort());
            int byteSize = buf.readableBytes();
            if (byteSize > 0) {
                byte[] block = new byte[byteSize];
                buf.readBytes(block);
                this.blockQueue.offer(block);
                DataStreamManageHolder.newInstance().dataStreamManager.readEvent(this);
            }
        } catch (IndexOutOfBoundsException e) {
            log.error(this.adapterKey, e);
        }
    }

    @Override
    public void pushData(ByteBuf buf, ChannelHandlerContext cx) {

    }
}
