/*
 * 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;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Application data type LCAF address class.
 * <p>
 * Application data type is defined in draft-ietf-lisp-lcaf-20
 * https://tools.ietf.org/html/draft-ietf-lisp-lcaf-20#page-27
 *
 * <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     |            Length             |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |       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() {

            checkNotNull(address, "Must specify an address");

            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);
        }
    }
}
