/*
 * Copyright 2016 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.routing.fpm.protocol;

import com.google.common.collect.ImmutableMap;
import org.onlab.packet.DeserializationException;

import java.nio.ByteBuffer;
import java.util.Map;

import static org.onlab.packet.PacketUtils.checkInput;

/**
 * Route attribute header.
 */
public abstract class RouteAttribute {

    public static final int ROUTE_ATTRIBUTE_HEADER_LENGTH = 4;

    public static final int RTA_DST = 1;
    public static final int RTA_OIF = 4;
    public static final int RTA_GATEWAY = 5;
    public static final int RTA_PRIORITY = 6;

    private final int length;
    private final int type;

    private static final Map<Integer, RouteAttributeDecoder<?>> TYPE_DECODER_MAP
            = ImmutableMap.<Integer, RouteAttributeDecoder<?>>builder()
            .put(RTA_DST, RouteAttributeDst.decoder())
            .put(RTA_OIF, RouteAttributeOif.decoder())
            .put(RTA_GATEWAY, RouteAttributeGateway.decoder())
            .put(RTA_PRIORITY, RouteAttributePriority.decoder())
            .build();

    /**
     * Class constructor.
     *
     * @param length attribute length
     * @param type attribute type
     */
    protected RouteAttribute(int length, int type) {
        this.length = length;
        this.type = type;
    }

    /**
     * Returns the attribute length.
     *
     * @return length
     */
    public int length() {
        return length;
    }

    /**
     * Returns the attribute type.
     *
     * @return type
     */
    public int type() {
        return type;
    }

    @Override
    public abstract String toString();

    /**
     * Decodes a route attribute from an input buffer.
     *
     * @param buffer input buffer
     * @param start starting position the route attribute message
     * @param length length of the message
     * @return route attribute message
     * @throws DeserializationException if a route attribute could not be
     * decoded from the input buffer
     */
    public static RouteAttribute decode(byte[] buffer, int start, int length)
            throws DeserializationException {
        checkInput(buffer, start, length, ROUTE_ATTRIBUTE_HEADER_LENGTH);

        ByteBuffer bb = ByteBuffer.wrap(buffer, start, length);

        int tlvLength = Short.reverseBytes(bb.getShort());
        int type = Short.reverseBytes(bb.getShort());

        if (bb.remaining() < tlvLength - ROUTE_ATTRIBUTE_HEADER_LENGTH) {
            throw new DeserializationException(
                    "Incorrect buffer size when decoding route attribute");
        }

        byte[] value = new byte[tlvLength - ROUTE_ATTRIBUTE_HEADER_LENGTH];
        bb.get(value);

        RouteAttributeDecoder<?> decoder = TYPE_DECODER_MAP.get(type);
        if (decoder == null) {
            throw new DeserializationException(
                    "No decoder found for route attribute type " + type);
        }

        return decoder.decodeAttribute(tlvLength, type, value);
    }
}
