/*
 * Copyright 2015-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.onlab.packet.pim;

import org.onlab.packet.DeserializationException;

import java.nio.ByteBuffer;
import java.text.MessageFormat;

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

/**
 * PIM HELLO option.
 */
public class PIMHelloOption {

    /*
     * PIM Option types.
     */
    public static final short OPT_HOLDTIME = 1;
    public static final short HOLDTIME_LENGTH = 2;
    public static final short DEFAULT_HOLDTIME = 105;

    public static final short OPT_PRUNEDELAY = 2;
    public static final short PRUNEDELAY_LENGTH = 4;
    public static final short DEFAULT_PRUNEDELAY = 500; // 500 ms
    public static final short DEFAULT_OVERRIDEINTERVAL = 2500; // 2500 ms

    public static final short OPT_PRIORITY = 19;
    public static final short PRIORITY_LENGTH = 4;
    public static final int DEFAULT_PRIORITY = 1;

    public static final short OPT_GENID = 20;
    public static final short GENID_LENGTH = 4;
    public static final int DEFAULT_GENID = 0;

    public static final short OPT_ADDRLIST = 24;

    public static final int MINIMUM_OPTION_LEN_BYTES = 4;

    // Values for this particular hello option.
    private short optType = 0;
    private short optLength = 0;
    private byte[] optValue;

    /**
     * Constructs a new hello option with no fields set.
     */
    public PIMHelloOption() {
    }

    /**
     * Set a PIM Hello option by type. The length and default value of the
     * type will be auto filled in by default.
     *
     * @param type hello option type
     */
    public PIMHelloOption(short type) {
        this.optType = type;
        switch (type) {
            case OPT_HOLDTIME:
                this.optLength = HOLDTIME_LENGTH;
                this.optValue = new byte[optLength];
                ByteBuffer.wrap(this.optValue).putShort(PIMHelloOption.DEFAULT_HOLDTIME);
                break;

            case OPT_PRUNEDELAY:
                this.optLength = PRUNEDELAY_LENGTH;
                this.optValue = new byte[this.optLength];
                ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRUNEDELAY);
                break;

            case OPT_PRIORITY:
                this.optLength = PRIORITY_LENGTH;
                this.optValue = new byte[this.optLength];
                ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRIORITY);
                break;

            case OPT_GENID:
                this.optLength = GENID_LENGTH;
                this.optValue = new byte[this.optLength];
                ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_GENID);
                break;

            case OPT_ADDRLIST:
                this.optLength = 0;   // We don't know what the length will be yet.
                this.optValue = null;
                break;

            default:
                //log.error("Unkown option type: " + type + "\n" );
                return;
        }
    }

    public void setOptType(short type) {
        this.optType = type;
    }

    public short getOptType() {
        return this.optType;
    }

    public void setOptLength(short len) {
        this.optLength = len;
    }

    public short getOptLength() {
        return this.optLength;
    }

    public void setValue(ByteBuffer bb) {
        this.optValue = new byte[this.optLength];
        bb.get(this.optValue, 0, this.optLength);
    }

    public void setValue(byte[] value) {
        this.optValue = value;
    }

    public byte[] getValue() {
        return this.optValue;
    }

    /**
     * Creates a new PIM Hello option with the specified values.
     *
     * @param type hello option type
     * @param length option length
     * @param value option value
     * @return new PIM Hello option
     */
    public static PIMHelloOption create(short type, short length, ByteBuffer value) {
        PIMHelloOption option = new PIMHelloOption();
        option.setOptType(type);
        option.setOptLength(length);
        value.rewind();
        option.setValue(value);
        return option;
    }

    /**
     * Creates a new priority option.
     *
     * @param priority priority
     * @return priority option
     */
    public static PIMHelloOption createPriority(int priority) {
        return create(OPT_PRIORITY, PRIORITY_LENGTH,
                ByteBuffer.allocate(PRIORITY_LENGTH).putInt(priority));
    }

    /**
     * Creates a new hold time option.
     *
     * @param holdTime hold time
     * @return hold time option
     */
    public static PIMHelloOption createHoldTime(short holdTime) {
        return create(OPT_HOLDTIME, HOLDTIME_LENGTH,
                ByteBuffer.allocate(HOLDTIME_LENGTH).putShort(holdTime));
    }

    /**
     * Creates a new generation ID option with a particular generation ID.
     *
     * @param genId generation ID value
     * @return generation ID option
     */
    public static PIMHelloOption createGenID(int genId) {
        return create(OPT_GENID, GENID_LENGTH,
                ByteBuffer.allocate(GENID_LENGTH).putInt(genId));
    }

    /**
     * Creates a new LAN Prune Delay option.
     *
     * @param propagationDelay prune delay
     * @param overrideInterval override interval
     * @return prune delay option
     */
    public static PIMHelloOption createPruneDelay(short propagationDelay, short overrideInterval) {
        return create(OPT_PRUNEDELAY, PRUNEDELAY_LENGTH,
                ByteBuffer.allocate(PRUNEDELAY_LENGTH)
                        .putShort(propagationDelay)
                        .putShort(overrideInterval));
    }

    public static PIMHelloOption deserialize(ByteBuffer bb) throws DeserializationException {
        checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), MINIMUM_OPTION_LEN_BYTES);

        PIMHelloOption opt = new PIMHelloOption();
        opt.setOptType(bb.getShort());
        opt.setOptLength(bb.getShort());

        checkBufferLength(bb.limit(), bb.position(), opt.getOptLength());
        opt.setValue(bb);

        return opt;
    }

    public byte[] serialize() {
        int len = MINIMUM_OPTION_LEN_BYTES + this.optLength;
        ByteBuffer bb = ByteBuffer.allocate(len);
        bb.putShort(this.optType);
        bb.putShort(this.optLength);
        bb.put(this.optValue);
        return bb.array();
    }

    public String toString() {
        return MessageFormat.format("Type: {0}, len: {1} value: {2}", this.optType, this.optLength,
                (this.optValue == null) ? "null" : this.optValue.toString());
    }

}
