/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.onosproject.xran.controller;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.sctp.SctpMessage;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.onosproject.net.DeviceId;
import org.onosproject.xran.codecs.pdu.XrancPdu;
import org.onosproject.xran.codecs.ber.BerByteArrayOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.bind.DatatypeConverter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;

import static org.onosproject.net.DeviceId.deviceId;

/**
 * Created by dimitris on 7/20/17.
 */

@Sharable
public class XranChannelHandler extends ChannelInboundHandlerAdapter {

    private static final Logger log =
            LoggerFactory.getLogger(XranChannelHandler.class);

    private final Controller controller;

    XranChannelHandler(Controller controller) {
        this.controller = controller;
    }

    public static SctpMessage getSctpMessage(XrancPdu pdu) throws IOException {
        BerByteArrayOutputStream os = new BerByteArrayOutputStream(4096);

        pdu.encode(os);

        log.debug("Sending message: {}", pdu);
        final ByteBuf buf = Unpooled.buffer(os.getArray().length);
        for (int i = 0; i < buf.capacity(); i++) {
            buf.writeByte(os.getArray()[i]);
        }
        return new SctpMessage(0, 0, buf);
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws IOException, URISyntaxException {
        final SocketAddress address = ctx.channel().remoteAddress();
        if (!(address instanceof InetSocketAddress)) {
            log.warn("Invalid client connection. Xran Cell is indentifed based on IP");
            ctx.close();
            return;
        }

        final InetSocketAddress inetAddress = (InetSocketAddress) address;
        final String host = inetAddress.getHostString();
        log.info("New client connected to the Server: {}", host);

        log.info("Adding device...");

        controller.deviceAgent.addConnectedCell(host, ctx);
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws IOException {
        SctpMessage sctpMessage = (SctpMessage) msg;
        ByteBuf byteBuf = sctpMessage.content();

        byte[] bytes = new byte[byteBuf.readableBytes()];
        byteBuf.readBytes(bytes);

        XrancPdu recv_pdu = new XrancPdu();

        InputStream inputStream = new ByteArrayInputStream(bytes);

        recv_pdu.decode(inputStream);

        controller.packetAgent.handlePacket(recv_pdu, ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        log.info("Client dropped the connection");

        final SocketAddress address = ctx.channel().remoteAddress();
        if (!(address instanceof InetSocketAddress)) {
            log.warn("Invalid client connection. Xran Cell is indentifed based on IP");
            ctx.close();
            return;
        }

        final InetSocketAddress inetAddress = (InetSocketAddress) address;
        final String host = inetAddress.getHostString();

        controller.deviceAgent.removeConnectedCell(host);

        ctx.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        log.warn("exceptionCaught: {}", ExceptionUtils.getStackTrace(cause));
        cause.printStackTrace();
        ctx.close();
    }
}

