/*
 * 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.Constants;
import org.onosproject.bgpio.util.Validation;

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

/**
 * Implementation of NextHop BGP Path Attribute.
 */
public class NextHop implements BgpValueType {
    public static final byte NEXTHOP_TYPE = 3;

    private boolean isNextHop = false;
    private Ip4Address nextHop;

    /**
     * Constructor to initialize parameters.
     *
     * @param nextHop nextHop address
     */
    public NextHop(Ip4Address nextHop) {
        this.nextHop = Preconditions.checkNotNull(nextHop);
        this.isNextHop = true;
    }

    /**
     * Returns whether next hop is present.
     *
     * @return whether next hop is present
     */
    public boolean isNextHopSet() {
        return this.isNextHop;
    }

    /**
     * Reads from ChannelBuffer and parses NextHop.
     *
     * @param cb ChannelBuffer
     * @return object of NextHop
     * @throws BgpParseException while parsing nexthop attribute
     */
    public static NextHop read(ChannelBuffer cb) throws BgpParseException {
        Ip4Address nextHop;
        ChannelBuffer tempCb = cb.copy();
        Validation parseFlags = Validation.parseAttributeHeader(cb);

        if (cb.readableBytes() < parseFlags.getLength()) {
            Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_LENGTH_ERROR,
                    parseFlags.getLength());
        }
        int len = parseFlags.isShort() ? parseFlags.getLength() + Constants.TYPE_AND_LEN_AS_SHORT : parseFlags
                .getLength() + Constants.TYPE_AND_LEN_AS_BYTE;
        ChannelBuffer data = tempCb.readBytes(len);
        if (parseFlags.getFirstBit() && !parseFlags.getSecondBit() && parseFlags.getThirdBit()) {
            throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR, BgpErrorType.ATTRIBUTE_FLAGS_ERROR, data);
        }

         InetAddress ipAddress = Validation.toInetAddress(parseFlags.getLength(), cb);
        if (ipAddress.isMulticastAddress()) {
            throw new BgpParseException("Multicast address is not supported");
        }

        nextHop = Ip4Address.valueOf(ipAddress);
        return new NextHop(nextHop);
    }

    /**
     * Return nexthop address.
     *
     * @return nexthop address
     */
    public Ip4Address nextHop() {
        return nextHop;
    }

    @Override
    public short getType() {
        return NEXTHOP_TYPE;
    }

    @Override
    public int write(ChannelBuffer cb) {
        //Not required to be implemented now
        return 0;
    }

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

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof NextHop) {
            NextHop other = (NextHop) obj;
            return Objects.equals(nextHop, other.nextHop);
        }
        return false;
    }

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