/*
 * 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.lisp.msg.types;

import io.netty.buffer.ByteBuf;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import org.onosproject.lisp.msg.exceptions.LispWriterException;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Objects;

import static com.google.common.base.MoreObjects.toStringHelper;

/**
 * Application data type LCAF address class.
 * <p>
 * Application data type is defined in draft-ietf-lisp-lcaf-13
 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-13#page-26
 *
 * <pre>
 * {@literal
 *  0                   1                   2                   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |           AFI = 16387         |     Rsvd1     |     Flags     |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |   Type = 4    |     Rsvd2     |            12 + n             |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |       IP TOS, IPv6 TC, or Flow Label          |    Protocol   |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |    Local Port (lower-range)   |    Local Port (upper-range)   |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |   Remote Port (lower-range)   |   Remote Port (upper-range)   |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |              AFI = x          |         Address  ...          |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * }</pre>
 */
public final class LispAppDataLcafAddress extends LispLcafAddress {

    private final byte protocol;
    private final int ipTos;
    private final short localPortLow;
    private final short localPortHigh;
    private final short remotePortLow;
    private final short remotePortHigh;
    private LispAfiAddress address;

    /**
     * Initializes application data type LCAF address.
     *
     * @param protocol       protocol number
     * @param ipTos          IP type of service
     * @param localPortLow   low-ranged local port number
     * @param localPortHigh  high-ranged local port number
     * @param remotePortLow  low-ranged remote port number
     * @param remotePortHigh high-ranged remote port number
     * @param address        address
     */
    private LispAppDataLcafAddress(byte protocol, int ipTos, short localPortLow,
                                   short localPortHigh, short remotePortLow,
                                   short remotePortHigh, LispAfiAddress address) {
        super(LispCanonicalAddressFormatEnum.APPLICATION_DATA);
        this.protocol = protocol;
        this.ipTos = ipTos;
        this.localPortLow = localPortLow;
        this.localPortHigh = localPortHigh;
        this.remotePortLow = remotePortLow;
        this.remotePortHigh = remotePortHigh;
        this.address = address;
    }

    /**
     * Initializes application data type LCAF address.
     *
     * @param reserved1      reserved1
     * @param reserved2      reserved2
     * @param flag           flag
     * @param length         length
     * @param protocol       protocol number
     * @param ipTos          IP type of service
     * @param localPortLow   low-ranged local port number
     * @param localPortHigh  high-ranged local port number
     * @param remotePortLow  low-ranged remote port number
     * @param remotePortHigh high-ranged remote port number
     * @param address        address
     */
    private LispAppDataLcafAddress(byte reserved1, byte reserved2, byte flag, short length,
                                   byte protocol, int ipTos, short localPortLow,
                                   short localPortHigh, short remotePortLow,
                                   short remotePortHigh, LispAfiAddress address) {
        super(LispCanonicalAddressFormatEnum.APPLICATION_DATA, reserved1, reserved2, flag, length);
        this.protocol = protocol;
        this.ipTos = ipTos;
        this.localPortLow = localPortLow;
        this.localPortHigh = localPortHigh;
        this.remotePortLow = remotePortLow;
        this.remotePortHigh = remotePortHigh;
        this.address = address;
    }

    /**
     * Obtains protocol number.
     *
     * @return protocol number
     */
    public byte getProtocol() {
        return protocol;
    }

    /**
     * Obtains IP type of service.
     *
     * @return IP type of service
     */
    public int getIpTos() {
        return ipTos;
    }

    /**
     * Obtains low-ranged local port number.
     *
     * @return low-ranged local port number
     */
    public short getLocalPortLow() {
        return localPortLow;
    }

    /**
     * Obtains high-ranged local port number.
     *
     * @return high-ranged local port number
     */
    public short getLocalPortHigh() {
        return localPortHigh;
    }

    /**
     * Obtains low-ranged remote port number.
     *
     * @return low-ranged remote port number
     */
    public short getRemotePortLow() {
        return remotePortLow;
    }

    /**
     * Obtains high-ranged remote port number.
     *
     * @return high-ranged remote port number
     */
    public short getRemotePortHigh() {
        return remotePortHigh;
    }

    /**
     * Obtains address.
     *
     * @return address
     */
    public LispAfiAddress getAddress() {
        return address;
    }

    @Override
    public int hashCode() {
        return Objects.hash(address, protocol, ipTos, localPortLow,
                localPortHigh, remotePortLow, remotePortHigh);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj instanceof LispAppDataLcafAddress) {
            final LispAppDataLcafAddress other = (LispAppDataLcafAddress) obj;
            return Objects.equals(this.address, other.address) &&
                    Objects.equals(this.protocol, other.protocol) &&
                    Objects.equals(this.ipTos, other.ipTos) &&
                    Objects.equals(this.localPortLow, other.localPortLow) &&
                    Objects.equals(this.localPortHigh, other.localPortHigh) &&
                    Objects.equals(this.remotePortLow, other.remotePortLow) &&
                    Objects.equals(this.remotePortHigh, other.remotePortHigh);
        }
        return false;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("address", address)
                .add("protocol", protocol)
                .add("ip type of service", ipTos)
                .add("low-ranged local port number", localPortLow)
                .add("high-ranged local port number", localPortHigh)
                .add("low-ranged remote port number", remotePortLow)
                .add("high-ranged remote port number", remotePortHigh)
                .toString();
    }

    public static final class AppDataAddressBuilder
            extends LcafAddressBuilder<AppDataAddressBuilder> {
        private byte protocol;
        private int ipTos;
        private short localPortLow;
        private short localPortHigh;
        private short remotePortLow;
        private short remotePortHigh;
        private LispAfiAddress address;

        /**
         * Sets protocol number.
         *
         * @param protocol protocol number
         * @return AppDataAddressBuilder object
         */
        public AppDataAddressBuilder withProtocol(byte protocol) {
            this.protocol = protocol;
            return this;
        }

        /**
         * Sets IP type of service.
         *
         * @param ipTos IP type of service
         * @return AppDataAddressBuilder object
         */
        public AppDataAddressBuilder withIpTos(int ipTos) {
            this.ipTos = ipTos;
            return this;
        }

        /**
         * Sets low-ranged local port number.
         *
         * @param localPortLow low-ranged local port number
         * @return AppDataAddressBuilder object
         */
        public AppDataAddressBuilder withLocalPortLow(short localPortLow) {
            this.localPortLow = localPortLow;
            return this;
        }

        /**
         * Sets high-ranged local port number.
         *
         * @param localPortHigh high-ranged local port number
         * @return AppDataAddressBuilder object
         */
        public AppDataAddressBuilder withLocalPortHigh(short localPortHigh) {
            this.localPortHigh = localPortHigh;
            return this;
        }

        /**
         * Sets low-ranged remote port number.
         *
         * @param remotePortLow low-ranged remote port number
         * @return AppDataAddressBuilder object
         */
        public AppDataAddressBuilder withRemotePortLow(short remotePortLow) {
            this.remotePortLow = remotePortLow;
            return this;
        }

        /**
         * Sets high-ranged remote port number.
         *
         * @param remotePortHigh high-ranged remote port number
         * @return AppDataAddressBuilder object
         */
        public AppDataAddressBuilder withRemotePortHigh(short remotePortHigh) {
            this.remotePortHigh = remotePortHigh;
            return this;
        }

        /**
         * Sets AFI address.
         *
         * @param address AFI address
         * @return AppDataAddressBuilder object
         */
        public AppDataAddressBuilder withAddress(LispAfiAddress address) {
            this.address = address;
            return this;
        }

        /**
         * Builds LispAppDataLcafAddress instance.
         *
         * @return LispAddDataLcafAddress instance
         */
        public LispAppDataLcafAddress build() {
            return new LispAppDataLcafAddress(reserved1, reserved2, flag, length,
                    protocol, ipTos, localPortLow, localPortHigh, remotePortLow,
                    remotePortHigh, address);
        }
    }

    /**
     * Application data LCAF address reader class.
     */
    public static class AppDataLcafAddressReader
            implements LispAddressReader<LispAppDataLcafAddress> {

        @Override
        public LispAppDataLcafAddress readFrom(ByteBuf byteBuf) throws LispParseError, LispReaderException {

            LispLcafAddress lcafAddress = LispLcafAddress.deserializeCommon(byteBuf);

            byte[] ipTosByte = new byte[3];
            byteBuf.readBytes(ipTosByte);

            byte protocol = (byte) byteBuf.readUnsignedByte();
            int ipTos = getPartialInt(ipTosByte);
            short localPortLow = (short) byteBuf.readUnsignedShort();
            short localPortHigh = (short) byteBuf.readUnsignedShort();
            short remotePortLow = (short) byteBuf.readUnsignedShort();
            short remotePortHigh = (short) byteBuf.readUnsignedShort();

            LispAfiAddress address = new LispAfiAddress.AfiAddressReader().readFrom(byteBuf);

            return new AppDataAddressBuilder()
                    .withReserved1(lcafAddress.getReserved1())
                    .withReserved2(lcafAddress.getReserved2())
                    .withFlag(lcafAddress.getFlag())
                    .withLength(lcafAddress.getLength())
                    .withProtocol(protocol)
                    .withIpTos(ipTos)
                    .withLocalPortLow(localPortLow)
                    .withLocalPortHigh(localPortHigh)
                    .withRemotePortLow(remotePortLow)
                    .withRemotePortHigh(remotePortHigh)
                    .withAddress(address)
                    .build();
        }

        /**
         * An utility function that obtains the partial int value from byte arrays.
         *
         * @param bytes an array of bytes
         * @return converted integer
         */
        public static int getPartialInt(byte[] bytes) {
            ByteBuffer buffer = ByteBuffer.allocate(4);
            buffer.position(4 - bytes.length);
            buffer.put(bytes);
            buffer.position(0);
            return buffer.getInt();
        }
    }

    /**
     * Application data LCAF address writer class.
     */
    public static class AppDataLcafAddressWriter
            implements LispAddressWriter<LispAppDataLcafAddress> {

        @Override
        public void writeTo(ByteBuf byteBuf, LispAppDataLcafAddress address)
                throws LispWriterException {

            LispLcafAddress.serializeCommon(byteBuf, address);

            byte[] tos = getPartialByteArray(address.getIpTos());
            byteBuf.writeBytes(tos);
            byteBuf.writeByte(address.getProtocol());
            byteBuf.writeShort(address.getLocalPortLow());
            byteBuf.writeShort(address.getLocalPortHigh());
            byteBuf.writeShort(address.getRemotePortLow());
            byteBuf.writeShort(address.getRemotePortHigh());

            AfiAddressWriter writer = new LispAfiAddress.AfiAddressWriter();
            writer.writeTo(byteBuf, address.getAddress());
        }

        /**
         * An utility function that obtains byte array from partial int value.
         *
         * @param value integer value
         * @return an array of bytes
         */
        public static byte[] getPartialByteArray(int value) {
            ByteBuffer buffer = ByteBuffer.allocate(4);
            byte[] array = buffer.putInt(value).array();
            return Arrays.copyOfRange(array, 1, 4);
        }
    }
}
