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

import org.onlab.packet.ipv6.Authentication;
import org.onlab.packet.ipv6.DestinationOptions;
import org.onlab.packet.ipv6.EncapSecurityPayload;
import org.onlab.packet.ipv6.Fragment;
import org.onlab.packet.ipv6.HopByHopOptions;
import org.onlab.packet.ipv6.IExtensionHeader;
import org.onlab.packet.ipv6.Routing;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

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

/**
 * Implements IPv6 packet format. (RFC 2460)
 */
public class IPv6 extends IP implements IExtensionHeader {
    public static final byte FIXED_HEADER_LENGTH = 40; // bytes

    public static final byte PROTOCOL_TCP = 0x6;
    public static final byte PROTOCOL_UDP = 0x11;
    public static final byte PROTOCOL_ICMP6 = 0x3A;
    public static final byte PROTOCOL_HOPOPT = 0x00;
    public static final byte PROTOCOL_ROUTING = 0x2B;
    public static final byte PROTOCOL_FRAG = 0x2C;
    public static final byte PROTOCOL_ESP = 0x32;
    public static final byte PROTOCOL_AH = 0x33;
    public static final byte PROTOCOL_DSTOPT = 0x3C;

    public static final byte LINK_LOCAL_0 = (byte) 0xfe;
    public static final byte LINK_LOCAL_1 = (byte) 0x80;

    public static final Map<Byte, Deserializer<? extends IPacket>> PROTOCOL_DESERIALIZER_MAP =
            new HashMap<>();

    static {
        IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_ICMP6, ICMP6.deserializer());
        IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_TCP, TCP.deserializer());
        IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_UDP, UDP.deserializer());
        IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_HOPOPT, HopByHopOptions.deserializer());
        IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_ROUTING, Routing.deserializer());
        IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_FRAG, Fragment.deserializer());
        IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_ESP, EncapSecurityPayload.deserializer());
        IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_AH, Authentication.deserializer());
        IPv6.PROTOCOL_DESERIALIZER_MAP.put(IPv6.PROTOCOL_DSTOPT, DestinationOptions.deserializer());
    }

    protected byte version;
    protected byte trafficClass;
    protected int flowLabel;
    protected short payloadLength;
    protected byte nextHeader;
    protected byte hopLimit;
    protected byte[] sourceAddress = new byte[Ip6Address.BYTE_LENGTH];
    protected byte[] destinationAddress = new byte[Ip6Address.BYTE_LENGTH];

    /**
     * Default constructor that sets the version to 6.
     */
    public IPv6() {
        super();
        this.version = 6;
    }

    @Override
    public byte getVersion() {
        return this.version;
    }

    @Override
    public IPv6 setVersion(final byte version) {
        this.version = version;
        return this;
    }

    /**
     * Gets traffic class.
     *
     * @return the traffic class
     */
    public byte getTrafficClass() {
        return this.trafficClass;
    }

    /**
     * Sets traffic class.
     *
     * @param trafficClass the traffic class to set
     * @return this
     */
    public IPv6 setTrafficClass(final byte trafficClass) {
        this.trafficClass = trafficClass;
        return this;
    }

    /**
     * Gets flow label.
     *
     * @return the flow label
     */
    public int getFlowLabel() {
        return this.flowLabel;
    }

    /**
     * Sets flow label.
     *
     * @param flowLabel the flow label to set
     * @return this
     */
    public IPv6 setFlowLabel(final int flowLabel) {
        this.flowLabel = flowLabel;
        return this;
    }

    @Override
    public byte getNextHeader() {
        return this.nextHeader;
    }

    @Override
    public IPv6 setNextHeader(final byte nextHeader) {
        this.nextHeader = nextHeader;
        return this;
    }

    /**
     * Gets hop limit.
     *
     * @return the hop limit
     */
    public byte getHopLimit() {
        return this.hopLimit;
    }

    /**
     * Sets hop limit.
     *
     * @param hopLimit the hop limit to set
     * @return this
     */
    public IPv6 setHopLimit(final byte hopLimit) {
        this.hopLimit = hopLimit;
        return this;
    }

    /**
     * Gets source address.
     *
     * @return the IPv6 source address
     */
    public byte[] getSourceAddress() {
        return this.sourceAddress;
    }

    /**
     * Sets source address.
     *
     * @param sourceAddress the IPv6 source address to set
     * @return this
     */
    public IPv6 setSourceAddress(final byte[] sourceAddress) {
        this.sourceAddress = Arrays.copyOfRange(sourceAddress, 0, Ip6Address.BYTE_LENGTH);
        return this;
    }

    /**
     * Gets destination address.
     *
     * @return the IPv6 destination address
     */
    public byte[] getDestinationAddress() {
        return this.destinationAddress;
    }

    /**
     * Sets destination address.
     *
     * @param destinationAddress the IPv6 destination address to set
     * @return this
     */
    public IPv6 setDestinationAddress(final byte[] destinationAddress) {
        this.destinationAddress = Arrays.copyOfRange(destinationAddress, 0, Ip6Address.BYTE_LENGTH);
        return this;
    }

    @Override
    public byte[] serialize() {
        byte[] payloadData = null;
        if (this.payload != null) {
            this.payload.setParent(this);
            payloadData = this.payload.serialize();
        }

        this.payloadLength = 0;
        if (payloadData != null) {
            this.payloadLength = (short) payloadData.length;
        }

        final byte[] data = new byte[FIXED_HEADER_LENGTH + payloadLength];
        final ByteBuffer bb = ByteBuffer.wrap(data);

        bb.putInt((this.version & 0xf) << 28 | (this.trafficClass & 0xff) << 20 | this.flowLabel & 0xfffff);
        bb.putShort(this.payloadLength);
        bb.put(this.nextHeader);
        bb.put(this.hopLimit);
        bb.put(this.sourceAddress, 0, Ip6Address.BYTE_LENGTH);
        bb.put(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);

        if (payloadData != null) {
            bb.put(payloadData);
        }

        return data;
    }

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

        iscratch = bb.getInt();
        this.version = (byte) (iscratch >> 28 & 0xf);
        this.trafficClass = (byte) (iscratch >> 20 & 0xff);
        this.flowLabel = iscratch & 0xfffff;
        this.payloadLength = bb.getShort();
        this.nextHeader = bb.get();
        this.hopLimit = bb.get();
        bb.get(this.sourceAddress, 0, Ip6Address.BYTE_LENGTH);
        bb.get(this.destinationAddress, 0, Ip6Address.BYTE_LENGTH);

        Deserializer<? extends IPacket> deserializer;
        if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(this.nextHeader)) {
            deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(this.nextHeader);
        } else {
            deserializer = Data.deserializer();
        }
        try {
            this.payload = deserializer.deserialize(data, bb.position(),
                                                    bb.limit() - bb.position());
            this.payload.setParent(this);
        } catch (DeserializationException e) {
            return this;
        }

        return this;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 2521;
        int result = super.hashCode();
        ByteBuffer bb;
        bb = ByteBuffer.wrap(this.destinationAddress);
        for (int i = 0; i < 4; i++) {
            result = prime * result + bb.getInt();
        }
        result = prime * result + this.trafficClass;
        result = prime * result + this.flowLabel;
        result = prime * result + this.hopLimit;
        result = prime * result + this.nextHeader;
        result = prime * result + this.payloadLength;
        bb = ByteBuffer.wrap(this.sourceAddress);
        for (int i = 0; i < 4; i++) {
            result = prime * result + bb.getInt();
        }
        result = prime * result + this.version;
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (!super.equals(obj)) {
            return false;
        }
        if (!(obj instanceof IPv6)) {
            return false;
        }
        final IPv6 other = (IPv6) obj;
        if (!Arrays.equals(this.destinationAddress, other.destinationAddress)) {
            return false;
        }
        if (this.trafficClass != other.trafficClass) {
            return false;
        }
        if (this.flowLabel != other.flowLabel) {
            return false;
        }
        if (this.hopLimit != other.hopLimit) {
            return false;
        }
        if (this.nextHeader != other.nextHeader) {
            return false;
        }
        if (this.payloadLength != other.payloadLength) {
            return false;
        }
        if (!Arrays.equals(this.sourceAddress, other.sourceAddress)) {
            return false;
        }
        return true;
    }

    /**
     * Deserializer function for IPv6 packets.
     *
     * @return deserializer function
     */
    public static Deserializer<IPv6> deserializer() {
        return (data, offset, length) -> {
            checkInput(data, offset, length, FIXED_HEADER_LENGTH);

            IPv6 ipv6 = new IPv6();

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

            int iscratch = bb.getInt();

            ipv6.version = (byte) (iscratch >> 28 & 0xf);
            ipv6.trafficClass = (byte) (iscratch >> 20 & 0xff);
            ipv6.flowLabel = iscratch & 0xfffff;
            ipv6.payloadLength = bb.getShort();
            ipv6.nextHeader = bb.get();
            ipv6.hopLimit = bb.get();
            bb.get(ipv6.sourceAddress, 0, Ip6Address.BYTE_LENGTH);
            bb.get(ipv6.destinationAddress, 0, Ip6Address.BYTE_LENGTH);

            Deserializer<? extends IPacket> deserializer;
            if (IPv6.PROTOCOL_DESERIALIZER_MAP.containsKey(ipv6.nextHeader)) {
                deserializer = IPv6.PROTOCOL_DESERIALIZER_MAP.get(ipv6.nextHeader);
            } else {
                deserializer = Data.deserializer();
            }

            int remainingLength = bb.limit() - bb.position();
            int payloadLength = ipv6.payloadLength;
            int bytesToRead = (payloadLength <= remainingLength) ?
                    payloadLength : remainingLength;
            ipv6.payload = deserializer.deserialize(data, bb.position(), bytesToRead);
            ipv6.payload.setParent(ipv6);

            return ipv6;
        };
    }

    @Override
    public String toString() {
        return toStringHelper(getClass())
                .add("version", Byte.toString(version))
                .add("trafficClass", Byte.toString(trafficClass))
                .add("flowLabel", Integer.toString(flowLabel))
                .add("payloadLength", Short.toString(payloadLength))
                .add("nextHeader", Byte.toString(nextHeader))
                .add("hopLimit", Byte.toString(hopLimit))
                .add("sourceAddress", Arrays.toString(sourceAddress))
                .add("destinationAddress", Arrays.toString(destinationAddress))
                .toString();
    }

    /**
     * According to the RFC 4291, the solicitation node addresses are
     * formed by taking the low-order 24 bits of an address (unicast or anycast)
     * and appending those bits to the prefix FF02:0:0:0:0:1:FF00::/104.
     *
     * Solicited-Node Address:  FF02:0:0:0:0:1:FFXX:XXXX
     *
     * @param targetIp the unicast or anycast address
     * @return the computed solicitation node address
     */
    public static byte[] getSolicitNodeAddress(byte[] targetIp) {
        checkArgument(targetIp.length == Ip6Address.BYTE_LENGTH);
        return new byte[] {
                (byte) 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                0x00, 0x00, 0x00, 0x01, (byte) 0xff,
                targetIp[targetIp.length - 3],
                targetIp[targetIp.length - 2],
                targetIp[targetIp.length - 1]
        };
    }

    /**
     * According to the RFC 2464, an IPv6 packet with a multicast
     * destination address DST, consisting of the sixteen octets DST[1]
     * through DST[16], is transmitted to the Ethernet multicast address
     * whose first two octets are the value 3333 hexadecimal and whose last
     * four octets are the last four octets of DST.
     *
     *                   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     *                   |0 0 1 1 0 0 1 1|0 0 1 1 0 0 1 1|
     *                   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     *                   |   DST[13]     |   DST[14]     |
     *                   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     *                   |   DST[15]     |   DST[16]     |
     *                   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     *
     * @param targetIp the multicast address.
     * @return the multicast mac address
     */
    public static byte[] getMCastMacAddress(byte[] targetIp) {
        checkArgument(targetIp.length == Ip6Address.BYTE_LENGTH);
        return new byte[] {
                0x33, 0x33,
                targetIp[targetIp.length - 4],
                targetIp[targetIp.length - 3],
                targetIp[targetIp.length - 2],
                targetIp[targetIp.length - 1],
        };
    }

    /**
     * According to the RFC 4291, an IPv6 link local address is an IPv6
     * unicast address that can be automatically configured on any interface
     * using the link-local prefix FE80::/10 (1111 1110 10) and the interface
     * identifier in the modified EUI-64 format.
     *
     *    +----------------------------------------------------------------+
     *    |  10 bits   |         54 bits         |          64 bits        |
     *    +----------- +-------------------------+-------------------------+
     *    | 1111111010 |           0             |       interface ID      |
     *    +----------- +-------------------------+-------------------------+
     *
     * @param targetIp the ip address to verify
     * @return true if the ipv6 address is link local,
     * false otherwise
     */
    public static boolean isLinkLocalAddress(byte[] targetIp) {
        checkArgument(targetIp.length == Ip6Address.BYTE_LENGTH);
        return (targetIp[0] & 0xff) == 0xfe && (targetIp[1] & 0xc0) == 0x80;
    }

    /**
     * Returns the auto-generated link local address using the
     * mac address as parameter.
     *
     * @param macAddress the mac address to use
     * @return the ipv6 link local address
     */
    public static byte[] getLinkLocalAddress(byte[] macAddress) {
        checkArgument(macAddress.length == MacAddress.MAC_ADDRESS_LENGTH);
        return new byte[] {
                LINK_LOCAL_0,
                LINK_LOCAL_1,
                0, 0, 0, 0, 0, 0,
                (byte) (macAddress[0] ^ (1 << 1)),
                macAddress[1],
                macAddress[2],
                (byte) 0xff,
                (byte) 0xfe,
                macAddress[3],
                macAddress[4],
                macAddress[5],
        };
    }

    /**
     * Returns the mac address from the auto-generated
     * link local address.
     *
     * @param linkLocalAddress the ipv6 to use
     * @return the mac address
     */
    public static byte[] getMacAddress(byte[] linkLocalAddress) {
        return !isLinkLocalAddress(linkLocalAddress) ? null : new byte[] {
                (byte) (linkLocalAddress[8] ^ (1 << 1)),
                linkLocalAddress[9],
                linkLocalAddress[10],
                linkLocalAddress[13],
                linkLocalAddress[14],
                linkLocalAddress[15],
        };
    }



}
