/*
 * Copyright 2014 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.util.Objects;

/**
 * A class representing an IP prefix. A prefix consists of an IP address and
 * a subnet mask.
 * This class is immutable.
 * <p>
 * NOTE: The stored IP address in the result IP prefix is masked to
 * contain zeroes in all bits after the prefix length.
 * </p>
 */
public class IpPrefix {
    // Maximum network mask length
    public static final int MAX_INET_MASK_LENGTH = IpAddress.INET_BIT_LENGTH;
    public static final int MAX_INET6_MASK_LENGTH = IpAddress.INET6_BIT_LENGTH;

    private final IpAddress address;
    private final short prefixLength;

    /**
     * Constructor for given IP address, and a prefix length.
     *
     * @param address the IP address
     * @param prefixLength the prefix length
     * @throws IllegalArgumentException if the prefix length value is invalid
     */
    protected IpPrefix(IpAddress address, int prefixLength) {
        checkPrefixLength(address.version(), prefixLength);
        this.address = IpAddress.makeMaskedAddress(address, prefixLength);
        this.prefixLength = (short) prefixLength;
    }

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

    /**
     * Returns the IP address value of the prefix.
     *
     * @return the IP address value of the prefix
     */
    public IpAddress address() {
        return address;
    }

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

    /**
     * Gets the {@link Ip4Prefix} view of the IP prefix.
     *
     * @return the {@link Ip4Prefix} view of the IP prefix if it is IPv4,
     * otherwise null
     */
    public Ip4Prefix getIp4Prefix() {
        if (version() != Ip4Prefix.VERSION) {
            return null;
        }

        // Return this object itself if it is already instance of Ip4Prefix
        if (this instanceof Ip4Prefix) {
            return (Ip4Prefix) this;
        }
        return Ip4Prefix.valueOf(address.getIp4Address(), prefixLength);
    }

    /**
     * Gets the {@link Ip6Prefix} view of the IP prefix.
     *
     * @return the {@link Ip6Prefix} view of the IP prefix if it is IPv6,
     * otherwise null
     */
    public Ip6Prefix getIp6Prefix() {
        if (version() != Ip6Prefix.VERSION) {
            return null;
        }

        // Return this object itself if it is already instance of Ip6Prefix
        if (this instanceof Ip6Prefix) {
            return (Ip6Prefix) this;
        }
        return Ip6Prefix.valueOf(address.getIp6Address(), prefixLength);
    }

    /**
     * Converts an integer and a prefix length into an IPv4 prefix.
     *
     * @param address an integer representing the IPv4 address
     * @param prefixLength the prefix length
     * @return an IP prefix
     * @throws IllegalArgumentException if the prefix length value is invalid
     */
    public static IpPrefix valueOf(int address, int prefixLength) {
        return new IpPrefix(IpAddress.valueOf(address), prefixLength);
    }

    /**
     * Converts a byte array and a prefix length into an IP prefix.
     *
     * @param version the IP address version
     * @param address the IP address value stored in network byte order
     * @param prefixLength the prefix length
     * @return an IP prefix
     * @throws IllegalArgumentException if the prefix length value is invalid
     */
    public static IpPrefix valueOf(IpAddress.Version version, byte[] address,
                                   int prefixLength) {
        return new IpPrefix(IpAddress.valueOf(version, address), prefixLength);
    }

    /**
     * Converts an IP address and a prefix length into an IP prefix.
     *
     * @param address the IP address
     * @param prefixLength the prefix length
     * @return an IP prefix
     * @throws IllegalArgumentException if the prefix length value is invalid
     */
    public static IpPrefix valueOf(IpAddress address, int prefixLength) {
        return new IpPrefix(address, prefixLength);
    }

    /**
     * Converts a CIDR (slash) notation string (e.g., "10.1.0.0/16" or
     * "1111:2222::/64") into an IP prefix.
     *
     * @param address an IP prefix in string form (e.g. "10.1.0.0/16" or
     * "1111:2222::/64")
     * @return an IP prefix
     * @throws IllegalArgumentException if the arguments are invalid
     */
    public static IpPrefix valueOf(String address) {
        final String[] parts = address.split("/");
        if (parts.length != 2) {
            String msg = "Malformed IP prefix string: " + address + "." +
                "Address must take form \"x.x.x.x/y\" or " +
                "\"xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx/y\"";
            throw new IllegalArgumentException(msg);
        }
        IpAddress ipAddress = IpAddress.valueOf(parts[0]);
        int prefixLength = Integer.parseInt(parts[1]);

        return new IpPrefix(ipAddress, prefixLength);
    }

    /**
     * Determines whether a given IP prefix is contained within this prefix.
     *
     * @param other the IP prefix to test
     * @return true if the other IP prefix is contained in this prefix,
     * otherwise false
     */
    public boolean contains(IpPrefix other) {
        if (version() != other.version()) {
            return false;
        }

        if (this.prefixLength > other.prefixLength) {
            return false;               // This prefix has smaller prefix size
        }

        //
        // Mask the other address with my prefix length.
        // If the other prefix is within this prefix, the masked address must
        // be same as the address of this prefix.
        //
        IpAddress maskedAddr =
            IpAddress.makeMaskedAddress(other.address, this.prefixLength);
        return this.address.equals(maskedAddr);
    }

    /**
     * Determines whether a given IP address is contained within this prefix.
     *
     * @param other the IP address to test
     * @return true if the IP address is contained in this prefix, otherwise
     * false
     */
    public boolean contains(IpAddress other) {
        if (version() != other.version()) {
            return false;
        }

        //
        // Mask the other address with my prefix length.
        // If the other prefix is within this prefix, the masked address must
        // be same as the address of this prefix.
        //
        IpAddress maskedAddr =
            IpAddress.makeMaskedAddress(other, this.prefixLength);
        return this.address.equals(maskedAddr);
    }

    @Override
    public int hashCode() {
        return Objects.hash(address, prefixLength);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if ((obj == null) || (!(obj instanceof IpPrefix))) {
            return false;
        }
        IpPrefix other = (IpPrefix) obj;
        return ((prefixLength == other.prefixLength) &&
                address.equals(other.address));
    }

    @Override
    /*
     * (non-Javadoc)
     * The format is "x.x.x.x/y" for IPv4 prefixes.
     *
     * @see java.lang.Object#toString()
     */
    public String toString() {
        final StringBuilder builder = new StringBuilder();
        builder.append(address.toString());
        builder.append("/");
        builder.append(String.format("%d", prefixLength));
        return builder.toString();
    }

    /**
     * Checks whether the prefix length is valid.
     *
     * @param version the IP address version
     * @param prefixLength the prefix length value to check
     * @throws IllegalArgumentException if the prefix length value is invalid
     */
    private static void checkPrefixLength(IpAddress.Version version,
                                          int prefixLength) {
        int maxPrefixLen = 0;

        switch (version) {
        case INET:
            maxPrefixLen = MAX_INET_MASK_LENGTH;
            break;
        case INET6:
            maxPrefixLen = MAX_INET6_MASK_LENGTH;
            break;
        default:
            String msg = "Invalid IP version " + version;
            throw new IllegalArgumentException(msg);
        }

        if ((prefixLength < 0) || (prefixLength > maxPrefixLen)) {
            String msg = "Invalid prefix length " + prefixLength + ". " +
                "The value must be in the interval [0, " +
                maxPrefixLen + "]";
            throw new IllegalArgumentException(msg);
        }
    }
}
