/*
 * 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 java.net.InetAddress;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Objects;
import com.google.common.net.InetAddresses;
import com.google.common.primitives.UnsignedBytes;


/**
 * A class representing an IP address.
 * This class is immutable.
 */
public class IpAddress implements Comparable<IpAddress> {
    private static final int BIT_MASK = 0x000000ff;

    // IP Versions
    public enum Version { INET, INET6 };

    // lengths of address, in bytes
    public static final int INET_BYTE_LENGTH = 4;
    public static final int INET_BIT_LENGTH = INET_BYTE_LENGTH * Byte.SIZE;
    public static final int INET6_BYTE_LENGTH = 16;
    public static final int INET6_BIT_LENGTH = INET6_BYTE_LENGTH * Byte.SIZE;

    private final Version version;
    private final byte[] octets;

    /**
     * Constructor for given IP address version and address octets.
     *
     * @param version the IP address version
     * @param value the IP address value stored in network byte order
     * (i.e., the most significant byte first)
     * @throws IllegalArgumentException if the arguments are invalid
     */
    protected IpAddress(Version version, byte[] value) {
        checkArguments(version, value, 0);
        this.version = version;
        switch (version) {
        case INET:
            this.octets = Arrays.copyOf(value, INET_BYTE_LENGTH);
            break;
        case INET6:
            this.octets = Arrays.copyOf(value, INET6_BYTE_LENGTH);
            break;
        default:
            // Should not be reached
            this.octets = null;
            break;
        }
    }

    /**
     * Returns the IP version of this address.
     *
     * @return the version
     */
    public Version version() {
        return this.version;
    }

    /**
     * Tests whether the IP version of this address is IPv4.
     *
     * @return true if the IP version of this address is IPv4, otherwise false.
     */
    public boolean isIp4() {
        return (version() == Ip4Address.VERSION);
    }

    /**
     * Tests whether the IP version of this address is IPv6.
     *
     * @return true if the IP version of this address is IPv6, otherwise false.
     */
    public boolean isIp6() {
        return (version() == Ip6Address.VERSION);
    }

    /**
     * Gets the {@link Ip4Address} view of the IP address.
     *
     * @return the {@link Ip4Address} view of the IP address if it is IPv4,
     * otherwise null
     */
    public Ip4Address getIp4Address() {
        if (!isIp4()) {
            return null;
        }

        // Return this object itself if it is already instance of Ip4Address
        if (this instanceof Ip4Address) {
            return (Ip4Address) this;
        }
        return Ip4Address.valueOf(octets);
    }

    /**
     * Gets the {@link Ip6Address} view of the IP address.
     *
     * @return the {@link Ip6Address} view of the IP address if it is IPv6,
     * otherwise null
     */
    public Ip6Address getIp6Address() {
        if (!isIp6()) {
            return null;
        }

        // Return this object itself if it is already instance of Ip6Address
        if (this instanceof Ip6Address) {
            return (Ip6Address) this;
        }
        return Ip6Address.valueOf(octets);
    }

    /**
     * Returns the IP address as a byte array.
     *
     * @return a byte array
     */
    public byte[] toOctets() {
        return Arrays.copyOf(octets, octets.length);
    }

    /**
     * Computes the IP address byte length for a given IP version.
     *
     * @param version the IP version
     * @return the IP address byte length for the IP version
     * @throws IllegalArgumentException if the IP version is invalid
     */
    public static int byteLength(Version version) {
        switch (version) {
        case INET:
            return INET_BYTE_LENGTH;
        case INET6:
            return INET6_BYTE_LENGTH;
        default:
            String msg = "Invalid IP version " + version;
            throw new IllegalArgumentException(msg);
        }
    }

    /**
     * Converts an integer into an IPv4 address.
     *
     * @param value an integer representing an IPv4 address value
     * @return an IP address
     */
    public static IpAddress valueOf(int value) {
        byte[] bytes =
            ByteBuffer.allocate(INET_BYTE_LENGTH).putInt(value).array();
        return new IpAddress(Version.INET, bytes);
    }

    /**
     * Converts a byte array into an IP address.
     *
     * @param version the IP address version
     * @param value the IP address value stored in network byte order
     * (i.e., the most significant byte first)
     * @return an IP address
     * @throws IllegalArgumentException if the arguments are invalid
     */
    public static IpAddress valueOf(Version version, byte[] value) {
        return new IpAddress(version, value);
    }

    /**
     * Converts a byte array and a given offset from the beginning of the
     * array into an IP address.
     * <p>
     * The IP address is stored in network byte order (i.e., the most
     * significant byte first).
     * </p>
     * @param version the IP address version
     * @param value the value to use
     * @param offset the offset in bytes from the beginning of the byte array
     * @return an IP address
     * @throws IllegalArgumentException if the arguments are invalid
     */
    public static IpAddress valueOf(Version version, byte[] value,
                                    int offset) {
        checkArguments(version, value, offset);
        byte[] bc = Arrays.copyOfRange(value, offset, value.length);
        return IpAddress.valueOf(version, bc);
    }

    /**
     * Converts an InetAddress into an IP address.
     *
     * @param inetAddress the InetAddress value to use
     * @return an IP address
     * @throws IllegalArgumentException if the argument is invalid
     */
    public static IpAddress valueOf(InetAddress inetAddress) {
        byte[] bytes = inetAddress.getAddress();
        if (inetAddress instanceof Inet4Address) {
            return new IpAddress(Version.INET, bytes);
        }
        if (inetAddress instanceof Inet6Address) {
            return new IpAddress(Version.INET6, bytes);
        }
        // Use the number of bytes as a hint
        if (bytes.length == INET_BYTE_LENGTH) {
            return new IpAddress(Version.INET, bytes);
        }
        if (bytes.length == INET6_BYTE_LENGTH) {
            return new IpAddress(Version.INET6, bytes);
        }
        final String msg = "Unrecognized IP version address string: " +
            inetAddress.toString();
        throw new IllegalArgumentException(msg);
    }

    /**
     * Converts an IPv4 or IPv6 string literal (e.g., "10.2.3.4" or
     * "1111:2222::8888") into an IP address.
     *
     * @param value an IP address value in string form
     * @return an IP address
     * @throws IllegalArgumentException if the argument is invalid
     */
    public static IpAddress valueOf(String value) {
        InetAddress inetAddress = null;
        try {
            inetAddress = InetAddresses.forString(value);
        } catch (IllegalArgumentException e) {
            final String msg = "Invalid IP address string: " + value;
            throw new IllegalArgumentException(msg);
        }
        return valueOf(inetAddress);
    }

    /**
     * Creates an IP network mask prefix.
     *
     * @param version the IP address version
     * @param prefixLength the length of the mask prefix. Must be in the
     * interval [0, 32] for IPv4, or [0, 128] for IPv6
     * @return a new IP address that contains a mask prefix of the
     * specified length
     * @throws IllegalArgumentException if the arguments are invalid
     */
    public static IpAddress makeMaskPrefix(Version version, int prefixLength) {
        byte[] mask = makeMaskPrefixArray(version, prefixLength);
        return new IpAddress(version, mask);
    }

    /**
     * Creates an IP address by masking it with a network mask of given
     * mask length.
     *
     * @param address the address to mask
     * @param prefixLength the length of the mask prefix. Must be in the
     * interval [0, 32] for IPv4, or [0, 128] for IPv6
     * @return a new IP address that is masked with a mask prefix of the
     * specified length
     * @throws IllegalArgumentException if the prefix length is invalid
     */
    public static IpAddress makeMaskedAddress(final IpAddress address,
                                              int prefixLength) {
        if (address instanceof Ip4Address) {
            Ip4Address ip4a = (Ip4Address) address;
            return Ip4Address.makeMaskedAddress(ip4a, prefixLength);
        } else if (address instanceof Ip6Address) {
            Ip6Address ip6a = (Ip6Address) address;
            return Ip6Address.makeMaskedAddress(ip6a, prefixLength);
        } else {
            byte[] net = makeMaskedAddressArray(address, prefixLength);
            return IpAddress.valueOf(address.version(), net);
        }
    }

    /**
     * Check if this IP address is zero.
     *
     * @return true if this address is zero
     */
    public boolean isZero() {
        for (byte b : octets) {
            if (b != 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * Check if this IP address is self-assigned.
     *
     * @return true if this address is self-assigned
     */
    public boolean isSelfAssigned() {
        return isIp4() && octets[0] == (byte) 169;
    }

    /**
     * Check if this IP address is a multicast address.
     *
     * @return true if this address a multicast address
     */
    public boolean isMulticast() {
        return isIp4() ?
                Ip4Prefix.IPV4_MULTICAST_PREFIX.contains(this.getIp4Address()) :
                Ip6Prefix.IPV6_MULTICAST_PREFIX.contains(this.getIp6Address());
    }

    @Override
    public int compareTo(IpAddress o) {
        // Compare first the version
        if (this.version != o.version) {
            return this.version.compareTo(o.version);
        }

        // Compare the bytes, one-by-one
        for (int i = 0; i < this.octets.length; i++) {
            if (this.octets[i] != o.octets[i]) {
                return UnsignedBytes.compare(this.octets[i], o.octets[i]);
            }
        }
        return 0;       // Equal
    }

    @Override
    public int hashCode() {
        return Objects.hash(version, Arrays.hashCode(octets));
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if ((obj == null) || (!(obj instanceof IpAddress))) {
            return false;
        }
        IpAddress other = (IpAddress) obj;
        return (version == other.version) &&
            Arrays.equals(octets, other.octets);
    }

    @Override
    /*
     * (non-Javadoc)
     * The string representation of the IP address: "x.x.x.x" for IPv4
     * addresses, or ':' separated string for IPv6 addresses.
     *
     * @see java.lang.Object#toString()
     */
    public String toString() {
        // FIXME InetAddress is super slow
        switch (version) {
            case INET:
                return String.format("%d.%d.%d.%d", octets[0] & 0xff,
                        octets[1] & 0xff,
                        octets[2] & 0xff,
                        octets[3] & 0xff);
            case INET6:
            default:
                return ipv6ToStringHelper();
        }
    }

    /**
     * Generates an IP prefix.
     *
     * @return the IP prefix of the IP address
     */
    public IpPrefix toIpPrefix() {

        if (isIp4()) {
            return IpPrefix.valueOf(new IpAddress(Version.INET, octets),
                                    Ip4Address.BIT_LENGTH);
        } else {
            return IpPrefix.valueOf(new IpAddress(Version.INET6, octets),
                                    Ip6Address.BIT_LENGTH);
        }
    }

    /**
     * Gets the IP address name for the IP address version.
     *
     * @param version the IP address version
     * @return the IP address name for the IP address version
     */
    private static String addressName(Version version) {
        switch (version) {
        case INET:
            return "IPv4";
        case INET6:
            return "IPv6";
        default:
            break;
        }
        return "UnknownIP(" + version + ")";
    }

    /**
     * Checks whether the arguments are valid.
     *
     * @param version the IP address version
     * @param value the IP address value stored in a byte array
     * @param offset the offset in bytes from the beginning of the byte
     * array with the address
     * @throws IllegalArgumentException if any of the arguments is invalid
     */
    static void checkArguments(Version version, byte[] value, int offset) {
        // Check the offset and byte array length
        int addrByteLength = byteLength(version);
        if ((offset < 0) || (offset + addrByteLength > value.length)) {
            String msg;
            if (value.length < addrByteLength) {
                msg = "Invalid " + addressName(version) +
                    " address array: array length: " + value.length +
                    ". Must be at least " + addrByteLength;
            } else {
                msg = "Invalid " + addressName(version) +
                    " address array: array offset: " + offset +
                    ". Must be in the interval [0, " +
                    (value.length - addrByteLength) + "]";
            }
            throw new IllegalArgumentException(msg);
        }
    }

    /**
     * Creates a byte array for IP network mask prefix.
     *
     * @param version the IP address version
     * @param prefixLength the length of the mask prefix. Must be in the
     * interval [0, 32] for IPv4, or [0, 128] for IPv6
     * @return a byte array that contains a mask prefix of the
     * specified length
     * @throws IllegalArgumentException if the arguments are invalid
     */
    static byte[] makeMaskPrefixArray(Version version, int prefixLength) {
        int addrByteLength = byteLength(version);
        int addrBitLength = addrByteLength * Byte.SIZE;

        // Verify the prefix length
        if ((prefixLength < 0) || (prefixLength > addrBitLength)) {
            final String msg = "Invalid IP prefix length: " + prefixLength +
                ". Must be in the interval [0, " + addrBitLength + "].";
            throw new IllegalArgumentException(msg);
        }

        // Number of bytes and extra bits that should be all 1s
        int maskBytes = prefixLength / Byte.SIZE;
        int maskBits = prefixLength % Byte.SIZE;
        byte[] mask = new byte[addrByteLength];

        // Set the bytes and extra bits to 1s
        for (int i = 0; i < maskBytes; i++) {
            mask[i] = (byte) 0xff;              // Set mask bytes to 1s
        }
        for (int i = maskBytes; i < addrByteLength; i++) {
            mask[i] = 0;                        // Set remaining bytes to 0s
        }
        if (maskBits > 0) {
            mask[maskBytes] = (byte) (0xff << (Byte.SIZE - maskBits));
        }
        return mask;
    }

    /**
     * Creates a byte array that represents an IP address masked with
     * a network mask of given mask length.
     *
     * @param addr the address to mask
     * @param prefixLength the length of the mask prefix. Must be in the
     * interval [0, 32] for IPv4, or [0, 128] for IPv6
     * @return a byte array that represents the IP address masked with
     * a mask prefix of the specified length
     * @throws IllegalArgumentException if the prefix length is invalid
     */
    static byte[] makeMaskedAddressArray(final IpAddress addr,
                                         int prefixLength) {
        byte[] mask = IpAddress.makeMaskPrefixArray(addr.version(),
                                                    prefixLength);
        byte[] net = new byte[mask.length];

        // Mask each byte
        for (int i = 0; i < net.length; i++) {
            net[i] = (byte) (addr.octets[i] & mask[i]);
        }
        return net;
    }

    /**
     * Creates a string based on the IPv6 recommendations for canonical representations found here:
     * https://tools.ietf.org/html/rfc5952#section-1.
     * @return A properly formatted IPv6 canonical representation.
     */
    private String ipv6ToStringHelper() {
        //Populate a buffer with the string of the full address with leading zeros stripped
        StringBuffer buff = new StringBuffer();
        buff.append(String.format("%x:%x:%x:%x:%x:%x:%x:%x",
                (((octets[0] & BIT_MASK) << 8) | (octets[1] & BIT_MASK)),
                (((octets[2] & BIT_MASK) << 8) | (octets[3] & BIT_MASK)),
                (((octets[4] & BIT_MASK) << 8) | (octets[5] & BIT_MASK)),
                (((octets[6] & BIT_MASK) << 8) | (octets[7] & BIT_MASK)),
                (((octets[8] & BIT_MASK) << 8) | (octets[9] & BIT_MASK)),
                (((octets[10] & BIT_MASK) << 8) | (octets[11] & BIT_MASK)),
                (((octets[12] & BIT_MASK) << 8) | (octets[13] & BIT_MASK)),
                (((octets[14] & BIT_MASK) << 8) | (octets[15] & BIT_MASK))));
        //Initialize variables for tracking longest zero subsequence, tiebreaking by first occurence
        int longestSeqStart, longestSeqLen, currSeqStart, currSeqLen;
        longestSeqStart = 0;
        longestSeqLen = 0;
        currSeqStart = 0;
        currSeqLen = 0;

        for (int index = 0; index < buff.length(); index++) {
            if (buff.charAt(index) == ':') {
                if (currSeqLen != 0 && buff.charAt(index + 1) == '0') {
                    currSeqLen += 1;
                }
            } else if (buff.charAt(index) == '0' && ((index == 0) || (buff.charAt(index - 1) == ':'))) {
                if (currSeqLen == 0) {
                    currSeqStart = index;
                }
                currSeqLen += 1;
            } else {
                 if (currSeqLen > longestSeqLen) {
                     longestSeqStart = currSeqStart;
                     longestSeqLen = currSeqLen;
                }
                currSeqLen = 0;
            }
        }

        if (currSeqLen > longestSeqLen) {
            longestSeqLen = currSeqLen;
            longestSeqStart = currSeqStart;
        }
        if (longestSeqLen > 1) {
            if (buff.length() == (longestSeqStart + longestSeqLen)) {
                buff.append(':');
            }

            buff.delete(longestSeqStart, longestSeqStart + longestSeqLen);

            if (longestSeqStart == 0) {
                buff.insert(0, ':');
            }
        }

    return buff.toString();
    }
}
