package org.onlab.packet;

import java.util.Arrays;



/**
 * A class representing an IPv4 address.
 * <p/>
 * TODO this class is a clone of IpPrefix and still needs to be modified to
 * look more like an IpAddress.
 */
public final class IpAddress implements Comparable<IpAddress> {

    // TODO a comparator for netmasks? E.g. for sorting by prefix match order.

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

    //lengths of address, in bytes
    public static final int INET_LEN = 4;
    public static final int INET6_LEN = 16;

    //maximum CIDR value
    public static final int MAX_INET_MASK = 32;
    //no mask (no network), e.g. a simple address
    public static final int DEFAULT_MASK = 0;

    /**
     * Default value indicating an unspecified address.
     */
    static final byte[] ANY = new byte [] {0, 0, 0, 0};

    protected Version version;

    protected byte[] octets;
    protected int netmask;

    private IpAddress(Version ver, byte[] octets, int netmask) {
        this.version = ver;
        this.octets = Arrays.copyOf(octets, INET_LEN);
        this.netmask = netmask;
    }

    private IpAddress(Version ver, byte[] octets) {
        this.version = ver;
        this.octets = Arrays.copyOf(octets, INET_LEN);
        this.netmask = DEFAULT_MASK;
    }

    /**
     * Converts a byte array into an IP address.
     *
     * @param address a byte array
     * @return an IP address
     */
    public static IpAddress valueOf(byte [] address) {
        return new IpAddress(Version.INET, address);
    }

    /**
     * Converts a byte array into an IP address.
     *
     * @param address a byte array
     * @param netmask the CIDR value subnet mask
     * @return an IP address
     */
    public static IpAddress valueOf(byte [] address, int netmask) {
        return new IpAddress(Version.INET, address, netmask);
    }

    /**
     * Helper to convert an integer into a byte array.
     *
     * @param address the integer to convert
     * @return a byte array
     */
    private static byte [] bytes(int address) {
        byte [] bytes = new byte [INET_LEN];
        for (int i = 0; i < INET_LEN; i++) {
            bytes[i] = (byte) ((address >> (INET_LEN - (i + 1)) * 8) & 0xff);
        }

        return bytes;
    }

    /**
     * Converts an integer into an IPv4 address.
     *
     * @param address an integer representing an IP value
     * @return an IP address
     */
    public static IpAddress valueOf(int address) {
        return new IpAddress(Version.INET, bytes(address));
    }

    /**
     * Converts an integer into an IPv4 address.
     *
     * @param address an integer representing an IP value
     * @param netmask the CIDR value subnet mask
     * @return an IP address
     */
    public static IpAddress valueOf(int address, int netmask) {
        return new IpAddress(Version.INET, bytes(address), netmask);
    }

    /**
     * Converts a dotted-decimal string (x.x.x.x) into an IPv4 address. The
     * string can also be in CIDR (slash) notation. If the netmask is omitted,
     * it will be set to DEFAULT_MASK (0).
     *
     * @param address a IP address in string form, e.g. "10.0.0.1", "10.0.0.1/24"
     * @return an IP address
     */
    public static IpAddress valueOf(String address) {

        final String [] parts = address.split("\\/");
        if (parts.length > 2) {
            throw new IllegalArgumentException("Malformed IP address string; "
                    + "Address must take form \"x.x.x.x\" or \"x.x.x.x/y\"");
        }

        int mask = DEFAULT_MASK;
        if (parts.length == 2) {
            mask = Integer.parseInt(parts[1]);
            if (mask > MAX_INET_MASK) {
                throw new IllegalArgumentException(
                        "Value of subnet mask cannot exceed "
                                + MAX_INET_MASK);
            }
        }

        final String [] net = parts[0].split("\\.");
        if (net.length != INET_LEN) {
            throw new IllegalArgumentException("Malformed IP address string; "
                    + "Address must have four decimal values separated by dots (.)");
        }
        final byte [] bytes = new byte[INET_LEN];
        for (int i = 0; i < INET_LEN; i++) {
            bytes[i] = (byte) Short.parseShort(net[i], 10);
        }
        return new IpAddress(Version.INET, bytes, mask);
    }

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

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

    /**
     * Returns the IP address prefix length.
     *
     * @return prefix length
     */
    public int prefixLength() {
        return netmask;
    }

    /**
     * Returns the integral value of this IP address.
     *
     * @return the IP address's value as an integer
     */
    public int toInt() {
        int val = 0;
        for (int i = 0; i < octets.length; i++) {
          val <<= 8;
          val |= octets[i] & 0xff;
        }
        return val;
    }

    /**
     * Converts the IP address to a /32 IP prefix.
     *
     * @return the new IP prefix
     */
    public IpPrefix toPrefix() {
        return IpPrefix.valueOf(octets, MAX_INET_MASK);
    }

    /**
     * Helper for computing the mask value from CIDR.
     *
     * @return an integer bitmask
     */
    private int mask() {
        int shift = MAX_INET_MASK - this.netmask;
        return ((Integer.MAX_VALUE >>> (shift - 1)) << shift);
    }

    /**
     * Returns the subnet mask in IpAddress form. The netmask value for
     * the returned IpAddress is 0, as the address itself is a mask.
     *
     * @return the subnet mask
     */
    public IpAddress netmask() {
        return new IpAddress(Version.INET, bytes(mask()));
    }

    /**
     * Returns the network portion of this address as an IpAddress.
     * The netmask of the returned IpAddress is the current mask. If this
     * address doesn't have a mask, this returns an all-0 IpAddress.
     *
     * @return the network address or null
     */
    public IpAddress network() {
        if (netmask == DEFAULT_MASK) {
            return new IpAddress(version, ANY, DEFAULT_MASK);
        }

        byte [] net = new byte [4];
        byte [] mask = bytes(mask());
        for (int i = 0; i < INET_LEN; i++) {
            net[i] = (byte) (octets[i] & mask[i]);
        }
        return new IpAddress(version, net, netmask);
    }

    /**
     * Returns the host portion of the IPAddress, as an IPAddress.
     * The netmask of the returned IpAddress is the current mask. If this
     * address doesn't have a mask, this returns a copy of the current
     * address.
     *
     * @return the host address
     */
    public IpAddress host() {
        if (netmask == DEFAULT_MASK) {
            new IpAddress(version, octets, netmask);
        }

        byte [] host = new byte [INET_LEN];
        byte [] mask = bytes(mask());
        for (int i = 0; i < INET_LEN; i++) {
            host[i] = (byte) (octets[i] & ~mask[i]);
        }
        return new IpAddress(version, host, netmask);
    }

    public boolean isMasked() {
        return mask() != 0;
    }

    /**
     * Determines whether a given address is contained within this IpAddress'
     * network.
     *
     * @param other another IP address that could be contained in this network
     * @return true if the other IP address is contained in this address'
     * network, otherwise false
     */
    public boolean contains(IpAddress other) {
        if (this.netmask <= other.netmask) {
            // Special case where they're both /32 addresses
            if (this.netmask == MAX_INET_MASK) {
                return Arrays.equals(octets, other.octets);
            }

            // Mask the other address with our network mask
            IpAddress otherMasked =
                    IpAddress.valueOf(other.octets, netmask).network();

            return network().equals(otherMasked);
        }
        return false;
    }

    @Override
    public int compareTo(IpAddress o) {
        Long lv = ((long) this.toInt()) & 0xffffffffL;
        Long rv = ((long) o.toInt()) & 0xffffffffL;
        return lv.compareTo(rv);
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + netmask;
        result = prime * result + Arrays.hashCode(octets);
        result = prime * result + ((version == null) ? 0 : version.hashCode());
        return result;
    }

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

    @Override
    /*
     * (non-Javadoc)
     * format is "x.x.x.x" for non-masked (netmask 0) addresses,
     * and "x.x.x.x/y" for masked addresses.
     *
     * @see java.lang.Object#toString()
     */
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        for (final byte b : this.octets) {
            if (builder.length() > 0) {
                builder.append(".");
            }
            builder.append(String.format("%d", b & 0xff));
        }
        if (netmask != DEFAULT_MASK) {
            builder.append("/");
            builder.append(String.format("%d", netmask));
        }
        return builder.toString();
    }

}
