/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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 org.slf4j.Logger;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Objects;

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

import static org.slf4j.LoggerFactory.getLogger;

/**
 * Default DHCP option.
 */
public class RIPngEntry extends BasePacket {
    public static final int OPT_CODE_LEN = 1;
    public static final int ENTRY_LEN = 20;
    public static final byte INFINITY_METRIC = 16;
    public static final byte NEXTHOP_METRIC =  -128; // actually it is 0xFF

    private final Logger log = getLogger(getClass());
    protected byte[] prefix; // 16 bytes
    protected short routeTag;
    protected byte prefixLen;
    protected byte metric;

    @Override
    public byte[] serialize() {
        ByteBuffer byteBuffer;
        byteBuffer = ByteBuffer.allocate(ENTRY_LEN);
        byteBuffer.put(prefix);
        byteBuffer.putShort(routeTag);
        byteBuffer.put(prefixLen);
        byteBuffer.put(metric);
        return byteBuffer.array();
    }

    /**
     * Deserializer function for RIPng entry.
     *
     * @return deserializer function
     */
    public static Deserializer<RIPngEntry> deserializer() {
        return (data, offset, length) -> {
            RIPngEntry ripngEntry = new RIPngEntry();

            checkNotNull(data);

            if (offset < 0 || length < 0 ||
                length > data.length || offset >= data.length ||
                offset + length > data.length) {
               throw new DeserializationException("Illegal offset or length");
            }
            ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
            if (bb.remaining() < ENTRY_LEN) {
               throw new DeserializationException(
                          "Buffer underflow while reading RIPng entry");
            }
            ripngEntry.prefix = new byte[IpAddress.INET6_BYTE_LENGTH];
            bb.get(ripngEntry.prefix);
            ripngEntry.routeTag = bb.getShort();
            ripngEntry.prefixLen = bb.get();
            ripngEntry.metric = bb.get();
            return ripngEntry;
        };
    }
    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        return Objects.hash(super.hashCode(), metric, prefixLen, Arrays.hashCode(prefix), routeTag);
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof RIPngEntry)) {
            return false;
        }
        final RIPngEntry that = (RIPngEntry) obj;

        return super.equals(that) &&
                Objects.equals(metric, that.metric) &&
                Objects.equals(routeTag, that.routeTag) &&
                Objects.equals(prefixLen, that.prefixLen) &&
                Arrays.equals(prefix, that.prefix) &&
                Objects.equals(routeTag, that.routeTag);
    }
    /**
     * @return the IPv6 prefix
     */
    public byte[] getPrefix() {
        return this.prefix;
    }

    /**
     * @param prefix the IPv6 prefix to set
     * @return this
     */
    public RIPngEntry setPrefix(final byte[] prefix) {
        this.prefix = prefix;
        return this;
    }

    /**
     * @return the route tag
     */
    public short getRouteTag() {
        return this.routeTag;
    }

    /**
     * @param routetag the route tag to set
     * @return this
     */
    public RIPngEntry setRouteTag(final short routetag) {
        this.routeTag = routetag;
        return this;
    }

    /**
     * @return the prefix length
     */
    public byte getPrefixLen() {
        return this.prefixLen;
    }

    /**
     * @param prefixlen the prefix length to set
     * @return this
     */
    public RIPngEntry setPrefixLen(final byte prefixlen) {
        this.prefixLen = prefixlen;
        return this;
    }

    /**
     * @return the metric
     */
    public byte getMetric() {
        return this.metric;
    }

    /**
     * @param metric the route metric to set
     * @return this
     */
    public RIPngEntry setMetric(final byte metric) {
        this.metric = metric;
        return this;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "RIPngEntry [prefix=" + Arrays.toString(this.prefix)
                + ", route tag=" + this.routeTag
                + ", prefix length=" + this.prefixLen
                + ", metric = " + this.metric + "]";
    }
}
