/*
 * 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.onosproject.net.host;

import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;

import java.util.Objects;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Represents a single IP address information on an interface.
 *
 * TODO:
 *  - Add computation for the default broadcast address if it is not
 *    specified
 *  - Add explicit checks that each IP address or prefix belong to the
 *    same IP version: IPv4/IPv6.
 *  - Inside the copy constructor we should use copy constructors for each
 *    field
 */
public class InterfaceIpAddress {
    private final IpAddress ipAddress;
    private final IpPrefix subnetAddress;
    private final IpAddress broadcastAddress;
    private final IpAddress peerAddress;

    /**
     * Copy constructor.
     *
     * @param other the object to copy from
     */
    public InterfaceIpAddress(InterfaceIpAddress other) {
        // TODO: we should use copy constructors for each field
        this.ipAddress = other.ipAddress;
        this.subnetAddress = other.subnetAddress;
        this.broadcastAddress = other.broadcastAddress;
        this.peerAddress = other.peerAddress;
    }

    /**
     * Constructor for a given IP address and a subnet address.
     *
     * @param ipAddress the IP address
     * @param subnetAddress the IP subnet address
     */
    public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress) {
        this.ipAddress = checkNotNull(ipAddress);
        this.subnetAddress = checkNotNull(subnetAddress);
        // TODO: Recompute the default broadcast address from the subnet
        // address
        this.broadcastAddress = null;
        this.peerAddress = null;
    }

    /**
     * Constructor for a given IP address and a subnet address.
     *
     * @param ipAddress the IP address
     * @param subnetAddress the IP subnet address
     * @param broadcastAddress the IP broadcast address. It can be used
     * to specify non-default broadcast address
     */
    public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress,
                              IpAddress broadcastAddress) {
        this.ipAddress = checkNotNull(ipAddress);
        this.subnetAddress = checkNotNull(subnetAddress);
        this.broadcastAddress = broadcastAddress;
        this.peerAddress = null;
    }

    /**
     * Constructor for a given IP address and a subnet address.
     *
     * @param ipAddress the IP address
     * @param subnetAddress the IP subnet address
     * @param broadcastAddress the IP broadcast address. It can be used
     * to specify non-default broadcast address. It should be null for
     * point-to-point interfaces with a peer address
     * @param peerAddress the peer IP address for point-to-point interfaces
     */
    public InterfaceIpAddress(IpAddress ipAddress, IpPrefix subnetAddress,
                              IpAddress broadcastAddress,
                              IpAddress peerAddress) {
        this.ipAddress = checkNotNull(ipAddress);
        this.subnetAddress = checkNotNull(subnetAddress);
        this.broadcastAddress = broadcastAddress;
        this.peerAddress = peerAddress;
    }

    /**
     * Gets the IP address.
     *
     * @return the IP address
     */
    public IpAddress ipAddress() {
        return ipAddress;
    }

    /**
     * Gets the IP subnet address.
     *
     * @return the IP subnet address
     */
    public IpPrefix subnetAddress() {
        return subnetAddress;
    }

    /**
     * Gets the subnet IP broadcast address.
     *
     * @return the subnet IP broadcast address
     */
    public IpAddress broadcastAddress() {
        return broadcastAddress;
    }

    /**
     * Gets the IP point-to-point interface peer address.
     *
     * @return the IP point-to-point interface peer address
     */
    public IpAddress peerAddress() {
        return peerAddress;
    }

    /**
     * Converts a CIDR string literal to an interface IP address.
     * E.g. 10.0.0.1/24
     *
     * @param value an IP address value in string form
     * @return an interface IP address
     * @throws IllegalArgumentException if the argument is invalid
     */
    public static InterfaceIpAddress valueOf(String value) {
        String[] splits = value.split("/");
        checkArgument(splits.length == 2, "Invalid IP address and prefix length format");

        // NOTE: IpPrefix will mask-out the bits after the prefix length.
        IpPrefix subnet = IpPrefix.valueOf(value);
        IpAddress addr = IpAddress.valueOf(splits[0]);
        return new InterfaceIpAddress(addr, subnet);
    }

    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }
        if (!(other instanceof InterfaceIpAddress)) {
            return false;
        }
        InterfaceIpAddress otherAddr = (InterfaceIpAddress) other;

        return Objects.equals(this.ipAddress, otherAddr.ipAddress)
            && Objects.equals(this.subnetAddress, otherAddr.subnetAddress)
            && Objects.equals(this.broadcastAddress,
                              otherAddr.broadcastAddress)
            && Objects.equals(this.peerAddress, otherAddr.peerAddress);
    }

    @Override
    public int hashCode() {
        return Objects.hash(ipAddress, subnetAddress, broadcastAddress,
                            peerAddress);
    }

    @Override
    public String toString() {
        /*return toStringHelper(this).add("ipAddress", ipAddress)
            .add("subnetAddress", subnetAddress)
            .add("broadcastAddress", broadcastAddress)
            .add("peerAddress", peerAddress)
            .omitNullValues().toString();*/
        return ipAddress.toString() + "/" + subnetAddress.prefixLength();
    }
}
