/*
 * Copyright 2015 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.bgpio.types;

import java.net.InetAddress;
import java.util.Objects;

import org.jboss.netty.buffer.ChannelBuffer;
import org.onlab.packet.Ip4Address;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.util.Validation;

import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;

/**
 * Provides Implementation of IPv4AddressTlv.
 */
public class IPv4AddressTlv implements BgpValueType {
    private static final int LENGTH = 4;

    private Ip4Address address;
    private short type;

    /**
     * Constructor to initialize parameters.
     *
     * @param address Ipv4 address of interface/neighbor
     * @param type address type
     */
    public IPv4AddressTlv(Ip4Address address, short type) {
        this.address = Preconditions.checkNotNull(address);
        this.type = type;
    }

    /**
     * Returns Ipv4 address of interface/neighbor.
     *
     * @return Ipv4 address of interface/neighbor
     */
    public Ip4Address address() {
        return address;
    }

    @Override
    public short getType() {
        return this.type;
    }

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

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof IPv4AddressTlv) {
            IPv4AddressTlv other = (IPv4AddressTlv) obj;
            return Objects.equals(this.address, other.address) && Objects.equals(this.type, other.type);
        }
        return false;
    }

    @Override
    public int write(ChannelBuffer cb) {
        int iLenStartIndex = cb.writerIndex();
        cb.writeShort(type);
        cb.writeShort(LENGTH);
        cb.writeInt(address.toInt());
        return cb.writerIndex() - iLenStartIndex;
    }

    /**
     * Reads the channel buffer and returns object of IPv4AddressTlv.
     *
     * @param cb channelBuffer
     * @param type address type
     * @return object of IPv4AddressTlv
     * @throws BgpParseException while parsing IPv4AddressTlv
     */
    public static IPv4AddressTlv read(ChannelBuffer cb, short type) throws BgpParseException {
        InetAddress ipAddress = Validation.toInetAddress(LENGTH, cb);
        if (ipAddress.isMulticastAddress()) {
            throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, (byte) 0, null);
        }
        Ip4Address address = Ip4Address.valueOf(ipAddress);
        return IPv4AddressTlv.of(address, type);
    }

    /**
     * Returns object of this class with specified values.
     *
     * @param address Ipv4 interface/neighbor Address
     * @param type says Ipv4 address of interface/neighbor tlv type
     * @return object of this class
     */
    public static IPv4AddressTlv of(final Ip4Address address , final short type) {
        return new IPv4AddressTlv(address, type);
    }

    @Override
    public int compareTo(Object o) {
        if (this.equals(o)) {
            return 0;
        }
        return ((Ip4Address) (this.address)).compareTo((Ip4Address) (((IPv4AddressTlv) o).address));
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("type", type)
                .add("LENGTH", LENGTH)
                .add("address", address)
                .toString();
    }
}