/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.nio.ByteBuffer;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * The class representing an IPv4 address.
 * This class is immutable.
 */
public final class Ip4Address implements Comparable<Ip4Address> {
    private final int value;

    /** The length of the address in bytes (octets). */
    public static final int BYTE_LENGTH = 4;

    /** The length of the address in bits. */
    public static final int BIT_LENGTH = BYTE_LENGTH * Byte.SIZE;

    /**
     * Default constructor.
     */
    public Ip4Address() {
        this.value = 0;
    }

    /**
     * Copy constructor.
     *
     * @param other the object to copy from
     */
    public Ip4Address(Ip4Address other) {
        this.value = other.value;
    }

    /**
     * Constructor from an integer value.
     *
     * @param value the value to use
     */
    public Ip4Address(int value) {
        this.value = value;
    }

    /**
     * Constructor from a byte array with the IPv4 address stored in network
     * byte order (i.e., the most significant byte first).
     *
     * @param value the value to use
     */
    public Ip4Address(byte[] value) {
        this(value, 0);
    }

    /**
     * Constructor from a byte array with the IPv4 address stored in network
     * byte order (i.e., the most significant byte first), and a given offset
     * from the beginning of the byte array.
     *
     * @param value the value to use
     * @param offset the offset in bytes from the beginning of the byte array
     */
    public Ip4Address(byte[] value, int offset) {
        checkNotNull(value);

        // Verify the arguments
        if ((offset < 0) || (offset + BYTE_LENGTH > value.length)) {
            String msg;
            if (value.length < BYTE_LENGTH) {
                msg = "Invalid IPv4 address array: array length: " +
                    value.length + ". Must be at least " + BYTE_LENGTH;
            } else {
                msg = "Invalid IPv4 address array: array offset: " +
                    offset + ". Must be in the interval [0, " +
                    (value.length - BYTE_LENGTH) + "]";
            }
            throw new IllegalArgumentException(msg);
        }

        // Read the address
        ByteBuffer bb = ByteBuffer.wrap(value);
        this.value = bb.getInt(offset);
    }

    /**
     * Constructs an IPv4 address from a string representation of the address.
     *<p>
     * Example: "1.2.3.4"
     *
     * @param value the value to use
     */
    public Ip4Address(String value) {
        checkNotNull(value);

        String[] splits = value.split("\\.");
        if (splits.length != 4) {
            final String msg = "Invalid IPv4 address string: " + value;
            throw new IllegalArgumentException(msg);
        }

        int result = 0;
        for (int i = 0; i < BYTE_LENGTH; i++) {
            result |= Integer.parseInt(splits[i]) <<
                ((BYTE_LENGTH - (i + 1)) * Byte.SIZE);
        }
        this.value = result;
    }

    /**
     * Gets the IPv4 address as a byte array.
     *
     * @return a byte array with the IPv4 address stored in network byte order
     * (i.e., the most significant byte first).
     */
    public byte[] toOctets() {
        return ByteBuffer.allocate(BYTE_LENGTH).putInt(value).array();
    }

    /**
     * Creates an IPv4 network mask prefix.
     *
     * @param prefixLen the length of the mask prefix. Must be in the interval
     * [0, 32].
     * @return a new IPv4 address that contains a mask prefix of the
     * specified length
     */
    public static Ip4Address makeMaskPrefix(int prefixLen) {
        // Verify the prefix length
        if ((prefixLen < 0) || (prefixLen > Ip4Address.BIT_LENGTH)) {
            final String msg = "Invalid IPv4 prefix length: " + prefixLen +
                ". Must be in the interval [0, 32].";
            throw new IllegalArgumentException(msg);
        }

        long v =
            (0xffffffffL << (Ip4Address.BIT_LENGTH - prefixLen)) & 0xffffffffL;
        return new Ip4Address((int) v);
    }

    /**
     * Creates an IPv4 address by masking it with a network mask of given
     * mask length.
     *
     * @param addr the address to mask
     * @param prefixLen the length of the mask prefix. Must be in the interval
     * [0, 32].
     * @return a new IPv4 address that is masked with a mask prefix of the
     * specified length
     */
    public static Ip4Address makeMaskedAddress(final Ip4Address addr,
                                               int prefixLen) {
        Ip4Address mask = Ip4Address.makeMaskPrefix(prefixLen);
        long v = addr.value & mask.value;

        return new Ip4Address((int) v);
    }

    /**
     * Gets the value of the IPv4 address.
     *
     * @return the value of the IPv4 address
     */
    public int getValue() {
        return value;
    }

    /**
     * Converts the IPv4 value to a '.' separated string.
     *
     * @return the IPv4 value as a '.' separated string
     */
    @Override
    public String toString() {
        return ((this.value >> 24) & 0xff) + "." +
                ((this.value >> 16) & 0xff) + "." +
                ((this.value >> 8) & 0xff) + "." +
                (this.value & 0xff);
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Ip4Address)) {
            return false;
        }
        Ip4Address other = (Ip4Address) o;
        if (this.value != other.value) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        return this.value;
    }

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