/*
 * Copyright 2015 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.onlab.packet.ndp;

import org.onlab.packet.BasePacket;
import org.onlab.packet.DeserializationException;
import org.onlab.packet.Deserializer;
import org.onlab.packet.IPacket;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.google.common.base.MoreObjects.toStringHelper;
import static org.onlab.packet.PacketUtils.checkInput;

/**
 * Neighbor Discovery Protocol packet options.
 */
public class NeighborDiscoveryOptions extends BasePacket {
    public static final byte TYPE_SOURCE_LL_ADDRESS = 1;
    public static final byte TYPE_TARGET_LL_ADDRESS = 2;
    public static final byte TYPE_PREFIX_INFORMATION = 3;
    public static final byte TYPE_REDIRECTED_HEADER = 4;
    public static final byte TYPE_MTU = 5;

    public static final byte INITIAL_HEADER_REQUIRED = 2;

    private static final String BUFFER_UNDERFLOW_ERROR =
            "Not enough bytes in buffer to read option";

    private final List<Option> options = new ArrayList<>();

    /**
     * Packet option.
     */
    public final class Option {
        private final byte type;
        private final byte[] data;

        /**
         * Constructor.
         *
         * @param type the option type
         * @param data the option data
         */
        private Option(byte type, byte[] data) {
            this.type = type;
            this.data = Arrays.copyOfRange(data, 0, data.length);
        }

        /**
         * Gets the option type.
         *
         * @return the option type
         */
        public byte type() {
            return this.type;
        }

        /**
         * Gets the option data.
         *
         * @return the option data
         */
        public byte[] data() {
            return this.data;
        }

        /**
         * Gets the option data length (in number of octets).
         *
         * @return the option data length (in number of octets)
         */
        public int dataLength() {
            return data.length;
        }

        /**
         * Gets the option length (in number of octets), including the type and
         * length fields (one octet each).
         *
         * @return the option length (in number of octets), including the type
         * and length fields
         */
        private int optionLength() {
            return 2 + dataLength();
        }

        /**
         * Gets the option length field value (in units of 8 octets).
         *
         * @return the option length field value (in units of 8 octets)
         */
        private byte optionLengthField() {
            return (byte) ((optionLength() + 7) / 8);
        }

        /**
         * Gets the option length on the wire (in number of octets).
         *
         * @return the option length on the wire (in number of octets)
         */
        private int optionWireLength() {
            return 8 * optionLengthField();
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("[");
            sb.append("type= ");
            sb.append(type);
            sb.append("data= ");
            sb.append(data);
            sb.append("]");
            return sb.toString();
        }
    }

    /**
     * Adds a Neighbor Discovery Protocol packet option.
     *
     * @param type the option type
     * @param data the option data
     * @return this
     */
    public NeighborDiscoveryOptions addOption(byte type, byte[] data) {
        options.add(new Option(type, data));
        return this;
    }

    /**
     * Gets the Neighbor Discovery Protocol packet options.
     *
     * @return the Neighbor Discovery Protocol packet options
     */
    public List<NeighborDiscoveryOptions.Option> options() {
        return this.options;
    }

    /**
     * Checks whether any options are included.
     *
     * @return true if options are included, otherwise false
     */
    public boolean hasOptions() {
        return !this.options.isEmpty();
    }

    @Override
    public byte[] serialize() {
        // Compute first the total length on the wire for all options

        int wireLength = 0;

        for (Option option : this.options) {
            wireLength += option.optionWireLength();
        }

        final byte[] data = new byte[wireLength];
        final ByteBuffer bb = ByteBuffer.wrap(data);

        //
        // Serialize all options
        //
        for (Option option : this.options) {
            bb.put(option.type());
            bb.put(option.optionLengthField());
            bb.put(option.data());
            // Add the padding
            int paddingLength =
                option.optionWireLength() - option.optionLength();
            for (int i = 0; i < paddingLength; i++) {
                bb.put((byte) 0);
            }
        }

        return data;
    }

    @Override
    public IPacket deserialize(byte[] data, int offset, int length) {
        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);

        options.clear();

        //
        // Deserialize all options
        //
        while (bb.hasRemaining()) {
            byte type = bb.get();
            if (!bb.hasRemaining()) {
                break;
            }
            byte lengthField = bb.get();
            int dataLength = lengthField * 8;   // The data length field is in
            // unit of 8 octets

            // Exclude the type and length fields
            if (dataLength < 2) {
                break;
            }
            dataLength -= 2;

            if (bb.remaining() < dataLength) {
                break;
            }
            byte[] optionData = new byte[dataLength];
            bb.get(optionData, 0, optionData.length);
            addOption(type, optionData);
        }

        return this;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;

        for (Option option : this.options) {
            result = prime * result + option.type();
            result = prime * result + Arrays.hashCode(option.data());
        }
        return result;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof NeighborDiscoveryOptions) {
            NeighborDiscoveryOptions other = (NeighborDiscoveryOptions) obj;
            return this.options.equals(other.options);
        }
        return false;
    }

    public static Deserializer<NeighborDiscoveryOptions> deserializer() {
        return (data, offset, length) -> {
            checkInput(data, offset, length, INITIAL_HEADER_REQUIRED);

            final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);

            NeighborDiscoveryOptions ndo = new NeighborDiscoveryOptions();

            ndo.options.clear();

            //
            // Deserialize all options
            //
            while (bb.hasRemaining()) {
                byte type = bb.get();
                if (!bb.hasRemaining()) {
                    throw new DeserializationException(BUFFER_UNDERFLOW_ERROR);
                }
                byte lengthField = bb.get();
                int dataLength = lengthField * 8;   // The data length field is in
                // unit of 8 octets

                // Exclude the type and length fields
                if (dataLength < 2) {
                    break;
                }
                dataLength -= 2;

                if (bb.remaining() < dataLength) {
                    throw new DeserializationException(BUFFER_UNDERFLOW_ERROR);
                }
                byte[] optionData = new byte[dataLength];
                bb.get(optionData, 0, optionData.length);
                ndo.addOption(type, optionData);
            }

            return ndo;
        };
    }

    @Override
    public String toString() {
        return toStringHelper(getClass())
                .toString();
        // TODO: need to handle options
    }
}
