/*
 * Copyright 2018-present Open Networking Foundation
 *
 * 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.openstacktelemetry.codec;

import org.onlab.packet.IpAddress;
import org.onlab.packet.IpAddress.Version;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onosproject.net.DeviceId;
import org.onosproject.openstacktelemetry.api.ByteBufferCodec;
import org.onosproject.openstacktelemetry.api.FlowInfo;
import org.onosproject.openstacktelemetry.api.StatsInfo;
import org.onosproject.openstacktelemetry.impl.DefaultFlowInfo;

import java.nio.ByteBuffer;

/**
 * FlowInfo ByteBuffer Codec.
 */
public class TinaFlowInfoByteBufferCodec extends ByteBufferCodec<FlowInfo> {

    private static final int MESSAGE_SIZE = 88;

    @Override
    public ByteBuffer encode(FlowInfo flowInfo) {

        ByteBuffer byteBuffer = ByteBuffer.allocate(MESSAGE_SIZE);

        byteBuffer.put(flowInfo.flowType())
                .putShort(Short.valueOf(flowInfo.deviceId().toString()))
                .putInt(flowInfo.inputInterfaceId())
                .putInt(flowInfo.outputInterfaceId())
                .putShort(flowInfo.vlanId().toShort())
                .put(flowInfo.srcIp().address().toOctets())
                .put((byte) flowInfo.srcIp().prefixLength())
                .putShort((short) flowInfo.srcPort().toInt())
                .put(flowInfo.dstIp().address().toOctets())
                .put((byte) flowInfo.dstIp().prefixLength())
                .putShort((short) flowInfo.dstPort().toInt())
                .put(flowInfo.protocol())
                .put(flowInfo.srcMac().toBytes())
                .put(flowInfo.dstMac().toBytes());

        TinaStatsInfoByteBufferCodec statsInfoByteBufferCodec =
                new TinaStatsInfoByteBufferCodec();
        byteBuffer.put(statsInfoByteBufferCodec.encode(flowInfo.statsInfo()).array());

        return byteBuffer;
    }

    @Override
    public FlowInfo decode(ByteBuffer byteBuffer) {

        byte flowType = byteBuffer.get();
        DeviceId deviceId = DeviceId.deviceId(String.valueOf(byteBuffer.getShort()));
        int inputInterfaceId = byteBuffer.getInt();
        int outputInterfaceId = byteBuffer.getInt();
        VlanId vlanId = VlanId.vlanId(byteBuffer.getShort());
        IpAddress srcIp = IpAddress.valueOf(Version.INET, getIpv4Octets(byteBuffer));
        int srcPrefixLen = byteBuffer.get();
        TpPort srcPort = TpPort.tpPort((int) byteBuffer.getShort());
        IpAddress dstIp = IpAddress.valueOf(Version.INET, getIpv4Octets(byteBuffer));
        int dstPrefixLen = byteBuffer.get();
        TpPort dstPort = TpPort.tpPort((int) byteBuffer.getShort());

        byte protocol = byteBuffer.get();
        MacAddress srcMac = MacAddress.valueOf(getMacByteArray(byteBuffer));
        MacAddress dstMac = MacAddress.valueOf(getMacByteArray(byteBuffer));

        TinaStatsInfoByteBufferCodec statsInfoByteBufferCodec =
                new TinaStatsInfoByteBufferCodec();
        StatsInfo statsInfo = statsInfoByteBufferCodec.decode(byteBuffer);

        return new DefaultFlowInfo.DefaultBuilder()
                .withFlowType(flowType)
                .withDeviceId(deviceId)
                .withInputInterfaceId(inputInterfaceId)
                .withOutputInterfaceId(outputInterfaceId)
                .withVlanId(vlanId)
                .withSrcIp(IpPrefix.valueOf(srcIp, srcPrefixLen))
                .withSrcPort(srcPort)
                .withDstIp(IpPrefix.valueOf(dstIp, dstPrefixLen))
                .withDstPort(dstPort)
                .withProtocol(protocol)
                .withSrcMac(srcMac)
                .withDstMac(dstMac)
                .withStatsInfo(statsInfo)
                .build();
    }

    /**
     * Obtains IPv4 Octets from ByteBuffer.
     *
     * @param buffer byte buffer
     * @return Ipv4 Octets
     */
    private byte[] getIpv4Octets(ByteBuffer buffer) {
        byte[] octets = new byte[4];
        for (int i = 0; i < octets.length; i++) {
            octets[i] = buffer.get();
        }
        return octets;
    }

    /**
     * Obtains MAC address byte array from ByteBuffer.
     *
     * @param buffer byte buffer
     * @return MAC address byte array
     */
    private byte[] getMacByteArray(ByteBuffer buffer) {
        byte[] array = new byte[6];
        for (int i = 0; i < array.length; i++) {
            array[i] = buffer.get();
        }
        return array;
    }
}
